---
openapi: 3.1.1
info:
  title: Catalog Service API
  description:
    Manages the catalog of products for the BookWorm platform, including
    books, authors, and categories
  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}.catalog.bookworm.com"
    description: Before deploying to production, ensure the environment is set correctly
    variables:
      protocol:
        enum:
          - https
          - http
          - grpc
        default: https
      environment:
        enum:
          - dev
          - stg
          - qa
        default: dev
  - url: "{protocol}://catalog.bookworm.com"
    description: Production environment
    variables:
      protocol:
        enum:
          - https
          - grpc
        default: https
security:
  - OAuth:
      - catalog
paths:
  "/api/v1/publishers":
    put:
      tags:
        - Publisher
      summary: Update Publisher
      description: Updates publisher if it exists
      x-eventcatalog-message-type: command
      operationId: UpdatePublisherEndpoint
      security:
        - OAuth:
            - catalog
      requestBody:
        description: The command to update the publisher
        content:
          application/json:
            schema:
              "$ref": "#/components/schemas/UpdatePublisherCommand"
            example:
              id: "01961eb7-be10-7235-bed8-2fea41c28c02"
              name: "O'Reilly Media, Inc."
        required: true
      responses:
        "204":
          description: No Content
        "400":
          description: Bad Request
          content:
            application/problem+json:
              schema:
                "$ref": "#/components/schemas/HttpValidationProblemDetails"
              examples:
                empty-publisher-id:
                  summary: Empty publisher 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: "Id"
                        errorMessage: "'Id' must not be empty."
                        severity: 0
                publisher-too-long:
                  summary: Publisher name too long
                  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: "Name"
                        errorMessage: "'Name' must be at most 50 characters."
                        severity: 0
        "401":
          description: Unauthorized - Access token is missing or invalid.
        "403":
          description: Forbidden - The permission requirements are not met.
    get:
      tags:
        - Publisher
      summary: List Publishers
      description: Lists all publishers
      x-eventcatalog-message-type: query
      operationId: ListPublishersEndpoint
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: array
                items:
                  "$ref": "#/components/schemas/PublisherDto"
              examples:
                publishers-empty:
                  summary: No publishers found
                  value: []
                publishers-single:
                  summary: Single publisher
                  value:
                    - id: "01961eb7-be10-7235-bed8-2fea41c28c02"
                      name: "O'Reilly Media, Inc."
                publishers-multiple:
                  summary: Multiple publishers
                  value:
                    - id: "01961eb7-be10-7235-bed8-2fea41c28c02"
                      name: "O'Reilly Media, Inc."
                    - id: "01961eb8-be10-7235-bed8-2fea41c28c03"
                      name: "Addison-Wesley Professional"
    post:
      tags:
        - Publisher
      summary: Create Publisher
      description: Creates a new publisher
      x-eventcatalog-message-type: command
      operationId: CreatePublisherEndpoint
      security:
        - OAuth:
            - catalog
      requestBody:
        description: The command to create a publisher
        content:
          application/json:
            schema:
              "$ref": "#/components/schemas/CreatePublisherCommand"
            example:
              name: "O'Reilly Media, Inc."
        required: true
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: string
                format: uuid
                description: The unique identifier of the publisher
                example: "01961eb4-668d-7e7e-ae25-0fab379614f7"
        "400":
          description: Bad Request
          content:
            application/problem+json:
              schema:
                "$ref": "#/components/schemas/HttpValidationProblemDetails"
              examples:
                empty-publisher-name:
                  summary: Empty publisher 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: "Name"
                        errorMessage: "'Name' must not be empty."
                        severity: 0
                publisher-name-too-long:
                  summary: Publisher name too long
                  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: "Name"
                        errorMessage: "'Name' must be at most 50 characters."
                        severity: 0
        "401":
          description: Unauthorized - Access token is missing or invalid.
        "403":
          description: Forbidden - The permission requirements are not met.
  "/api/v1/publishers/{id}":
    delete:
      tags:
        - Publisher
      summary: Delete Publisher
      description: Delete a publisher by identifier
      x-eventcatalog-message-type: command
      operationId: DeletePublisherEndpoint
      parameters:
        - name: id
          in: path
          description: The unique identifier of the publisher to be deleted
          required: true
          schema:
            type: string
            format: uuid
            description: The unique identifier of the publisher to be deleted
            example: "01961eb7-be10-7235-bed8-2fea41c28c02"
      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"
              example:
                type: "https://tools.ietf.org/html/rfc9110#section-15.5.1"
                title: "Not Found"
                status: 404
                detail: "Publisher with id 01961eb7-be10-7235-bed8-2fea41c28c02 not found."
  "/api/v1/categories":
    put:
      tags:
        - Category
      summary: Update Category
      description: Update a category if it exists
      x-eventcatalog-message-type: command
      operationId: UpdateCategoryEndpoint
      security:
        - OAuth:
            - catalog
      requestBody:
        description: The command to update the category
        content:
          application/json:
            schema:
              "$ref": "#/components/schemas/UpdateCategoryCommand"
            example:
              id: "01961eb4-668d-7e7e-ae25-0fab379614f7"
              name: "Programming"
        required: true
      responses:
        "204":
          description: No Content
        "400":
          description: Bad Request
          content:
            application/problem+json:
              schema:
                "$ref": "#/components/schemas/HttpValidationProblemDetails"
              examples:
                empty-category-id:
                  summary: Empty category 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: "Id"
                        errorMessage: "'Id' must not be empty."
                        severity: 0
                category-too-long:
                  summary: Category name too long
                  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: "Name"
                        errorMessage: "'Name' must be at most 50 characters."
                        severity: 0
        "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"
              example:
                type: "https://tools.ietf.org/html/rfc9110#section-15.5.1"
                title: "Not Found"
                status: 404
                detail: "Category with id 01961eb4-668d-7e7e-ae25-0fab379614f7 not found."
    get:
      tags:
        - Category
      summary: List Categories
      description: List all categories
      x-eventcatalog-message-type: query
      operationId: ListCategoriesEndpoint
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: array
                items:
                  "$ref": "#/components/schemas/CategoryDto"
              examples:
                categories-empty:
                  summary: No categories found
                  value: []
                categories-single:
                  summary: Single category
                  value:
                    - id: "01961eb4-668d-7e7e-ae25-0fab379614f7"
                      name: "Programming"
                categories-multiple:
                  summary: Multiple categories
                  value:
                    - id: "01961eb4-668d-7e7e-ae25-0fab379614f7"
                      name: "Programming"
                    - id: "01961eb5-668d-7e7e-ae25-0fab379614f7"
                      name: "Romance & Love"
    post:
      tags:
        - Category
      summary: Create Category
      description: Create a new category in the catalog system
      x-eventcatalog-message-type: command
      operationId: CreateCategoryEndpoint
      security:
        - OAuth:
            - catalog
      requestBody:
        description: The command to create a category
        content:
          application/json:
            schema:
              "$ref": "#/components/schemas/CreateCategoryCommand"
            example:
              name: "Programming"
        required: true
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: string
                format: uuid
                description: The unique identifier of the category
                example: "01961eb4-668d-7e7e-ae25-0fab379614f7"
        "400":
          description: Bad Request
          content:
            application/problem+json:
              schema:
                "$ref": "#/components/schemas/HttpValidationProblemDetails"
              examples:
                empty-category-name:
                  summary: Empty category 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: "Name"
                        errorMessage: "'Name' must not be empty."
                        severity: 0
                category-name-too-long:
                  summary: Category name too long
                  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: "Name"
                        errorMessage: "'Name' must be at most 50 characters."
                        severity: 0
        "401":
          description: Unauthorized - Access token is missing or invalid.
        "403":
          description: Forbidden - The permission requirements are not met.
  "/api/v1/categories/{id}":
    delete:
      tags:
        - Category
      summary: Delete Category
      description: Delete a category by identifier
      x-eventcatalog-message-type: command
      operationId: DeleteCategoryEndpoint
      parameters:
        - name: id
          in: path
          description: The unique identifier of the category to be deleted
          required: true
          schema:
            type: string
            format: uuid
            description: The unique identifier of the category 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"
              example:
                type: "https://tools.ietf.org/html/rfc9110#section-15.5.1"
                title: "Not Found"
                status: 404
                detail: "Category with id 01961eb4-668d-7e7e-ae25-0fab379614f7 not found."
  "/api/v1/books":
    put:
      tags:
        - Book
      summary: Update Book
      description: Update a book if it exists
      x-eventcatalog-message-type: command
      operationId: UpdateBookEndpoint
      security:
        - OAuth:
            - catalog
      requestBody:
        description: The command to update the book
        content:
          multipart/form-data:
            schema:
              required:
                - Id
                - Name
                - Price
                - CategoryId
                - PublisherId
                - AuthorIds
              type: object
              allOf:
                - type: object
                  properties:
                    Id:
                      type: string
                      format: uuid
                      description: The unique identifier of the book
                      example: "01961eb4-668d-7e7e-ae25-0fab379614f7"
                - type: object
                  properties:
                    Name:
                      type: string
                      description: The name of the book
                      example: "Software Architecture: The Hard Parts"
                      maxLength: 50
                - type: object
                  properties:
                    Description:
                      type: string
                      description: The description of the book
                      example: "When two of your authors, Neal and Mark, were writing the book Fundamentals of Software Architecture, we kept coming across complex examples in architecture that we wanted to cover but that were too difficult."
                      maxLength: 500
                - type: object
                  properties:
                    Image:
                      "$ref": "#/components/schemas/IFormFile"
                - type: object
                  properties:
                    Price:
                      type: number
                      format: double
                      description: The price of the book
                      example: 43.99
                      minimum: 0
                - type: object
                  properties:
                    PriceSale:
                      type: number
                      format: double
                      description: The sale price of the book
                      example: 39.86
                      minimum: 0
                      maximum: 100
                - type: object
                  properties:
                    CategoryId:
                      type: string
                      format: uuid
                      description: The category of the book
                      example: "01961eb2-5a5b-749f-b494-1063d73c96a3"
                - type: object
                  properties:
                    PublisherId:
                      type: string
                      format: uuid
                      description: The publisher of the book
                      example: "01961eb7-be10-7235-bed8-2fea41c28c02"
                - type: object
                  properties:
                    AuthorIds:
                      type: array
                      items:
                        type: string
                        format: uuid
                        description: The authors of the book
                        examples:
                          - "01961eb4-0c29-799f-ab78-ad3e2beaa54a"
                          - "01961ebd-2bc1-7de2-aa90-639662d9259e"
                - type: object
                  properties:
                    IsRemoveImage:
                      type: boolean
                      default: false
                      description: Whether to remove the image of the book
                      example: false
              example:
                Id: "01961eb4-668d-7e7e-ae25-0fab379614f7"
                Name: "Software Architecture: The Hard Parts"
                Description: "When two of your authors, Neal and Mark, were writing the book Fundamentals of Software Architecture, we kept coming across complex examples in architecture that we wanted to cover but that were too difficult."
                Image: "image.jpg"
                Price: 43.99
                PriceSale: 39.86
                CategoryId: "01961eb2-5a5b-749f-b494-1063d73c96a3"
                PublisherId: "01961eb7-be10-7235-bed8-2fea41c28c02"
                AuthorIds:
                  - "01961eb4-0c29-799f-ab78-ad3e2beaa54a"
                  - "01961ebd-2bc1-7de2-aa90-639662d9259e"
                IsRemoveImage: false
        required: true
      responses:
        "204":
          description: No Content
        "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: "Id"
                        errorMessage: "'Id' must not be empty."
                        severity: 0
                empty-book-name:
                  summary: Empty book 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: "Name"
                        errorMessage: "'Name' must not be empty."
                        severity: 0
                book-name-too-long:
                  summary: Book name too long
                  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: "Name"
                        errorMessage: "'Name' must be at most 50 characters."
                        severity: 0
        "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"
              example:
                type: "https://tools.ietf.org/html/rfc9110#section-15.5.1"
                title: "Not Found"
                status: 404
                detail: "Book with id 01961eb4-668d-7e7e-ae25-0fab379614f7 not found."
    get:
      tags:
        - Book
      summary: List Books
      description: List all books with advanced filtering and pagination
      x-eventcatalog-message-type: query
      operationId: ListBooksEndpoint
      parameters:
        - name: PageIndex
          in: query
          description: Number of items to return in a single page of results
          schema:
            type: integer
            format: int32
            default: 1
            example: 1
            minimum: 1
        - name: PageSize
          in: query
          description: Number of items to return in a single page of results
          schema:
            type: integer
            format: int32
            default: 20
            example: 20
            minimum: 1
        - name: OrderBy
          in: query
          description: Property to order results by
          schema:
            type: string
            default: Name
            example: "Name"
        - name: IsDescending
          in: query
          description: Whether to order results in descending order
          schema:
            type: boolean
            default: false
            example: false
        - name: Search
          in: query
          description: Search term to filter results by
          schema:
            type: string
            example: "Software"
        - name: MinPrice
          in: query
          description: Minimum price to filter results by
          schema:
            type: number
            format: double
        - name: MaxPrice
          in: query
          description: Maximum price to filter results by
          schema:
            type: number
            format: double
        - name: CategoryId
          in: query
          description: Category IDs to filter results by
          schema:
            type: array
            items:
              type: string
              format: uuid
        - name: PublisherId
          in: query
          description: Publisher IDs to filter results by
          schema:
            type: array
            items:
              type: string
              format: uuid
        - name: AuthorIds
          in: query
          description: Author IDs to filter results by
          schema:
            type: array
            items:
              type: string
              format: uuid
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/PagedResultOfBookDto"
              examples:
                books-empty:
                  summary: No books found
                  value:
                    items: []
                    pageIndex: 1
                    pageSize: 20
                    totalItems: 0
                    totalPages: 0
                    hasPreviousPage: false
                    hasNextPage: false
                books-single:
                  summary: Single book
                  value:
                    items:
                      - id: "01961eb4-668d-7e7e-ae25-0fab379614f7"
                        name: "Software Architecture: The Hard Parts"
                        description: "When two of your authors, Neal and Mark, were writing the book Fundamentals of Software Architecture, we kept coming across complex examples in architecture that we wanted to cover but that were too difficult."
                        image: "https://default.blob.core.windows.net/catalog/01961eb4-668d-7e7e-ae25-0fab379614f7-software-architecture-the-hard-parts.jpg?sv=2023-01-01&sr=b&st=2023-01-01T00%3A00%3A00Z&se=2023-01-01T01%3A00%3A00Z&sp=r&sig=XXXXX"
                        price: 43.99
                        priceSale: 39.86
                        status: "InStock"
                        category:
                          id: "01961eb2-5a5b-749f-b494-1063d73c96a3"
                          name: "Programming"
                        publisher:
                          id: "01961eb7-be10-7235-bed8-2fea41c28c02"
                          name: "O'Reilly Media, Inc."
                        authors:
                          - id: "01961eb4-0c29-799f-ab78-ad3e2beaa54a"
                            name: "Neal Ford"
                          - id: "01961ebd-2bc1-7de2-aa90-639662d9259e"
                            name: "Mark Richards"
                        averageRating: 4.5
                        totalReviews: 591
                    pageIndex: 1
                    pageSize: 20
                    totalItems: 1
                    totalPages: 1
                    hasPreviousPage: false
                    hasNextPage: false
                books-multiple:
                  summary: Multiple books
                  value:
                    items:
                      - id: "01961eb4-668d-7e7e-ae25-0fab379614f7"
                        name: "Software Architecture: The Hard Parts"
                        description: "When two of your authors, Neal and Mark, were writing the book Fundamentals of Software Architecture, we kept coming across complex examples in architecture that we wanted to cover but that were too difficult."
                        image: "https://default.blob.core.windows.net/catalog/01961eb4-668d-7e7e-ae25-0fab379614f7-software-architecture-the-hard-parts.jpg?sv=2023-01-01&sr=b&st=2023-01-01T00%3A00%3A00Z&se=2023-01-01T01%3A00%3A00Z&sp=r&sig=XXXXX"
                        price: 43.99
                        priceSale: 39.86
                        status: "InStock"
                        category:
                          id: "01961eb2-5a5b-749f-b494-1063d73c96a3"
                          name: "Programming"
                        publisher:
                          id: "01961eb7-be10-7235-bed8-2fea41c28c02"
                          name: "O'Reilly Media, Inc."
                        authors:
                          - id: "01961eb4-0c29-799f-ab78-ad3e2beaa54a"
                            name: "Neal Ford"
                          - id: "01961ebd-2bc1-7de2-aa90-639662d9259e"
                            name: "Mark Richards"
                        averageRating: 4.5
                        totalReviews: 591
                      - id: "01961eb5-668d-7e7e-ae25-0fab379614f7"
                        name: "The Pragmatic Programmer: From Journeyman to Master"
                        description: "The Pragmatic Programmer is a guide to the practice of programming - the art of building effective systems and the craft of creating great code. It offers advice on how to deal with the complexity of real-world software development, and the latest thinking on programming language design. The book is packed with concrete advice that you can use immediately to make your code better."
                        image: "https://default.blob.core.windows.net/catalog/01961eb5-668d-7e7e-ae25-0fab379614f7-the-pragmatic-programmer.jpg?sv=2023-01-01&sr=b&st=2023-01-01T00%3A00%3A00Z&se=2023-01-01T01%3A00%3A00Z&sp=r&sig=XXXXX"
                        price: 43.99
                        priceSale: 39.86
                        status: "InStock"
                        category:
                          id: "01961eb2-5a5b-749f-b494-1063d73c96a3"
                          name: "Programming"
                        publisher:
                          id: "01961eb7-be10-7235-bed8-2fea41c28c02"
                          name: "O'Reilly Media, Inc."
                        authors:
                          - id: "01961eb4-0c29-799f-ab78-ad3e2beaa54a"
                            name: "Andrew Hunt"
                          - id: "01961ebd-2bc1-7de2-aa90-639662d9259e"
                            name: "David Thomas"
                        averageRating: 4.5
                        totalReviews: 591
                    pageIndex: 1
                    pageSize: 20
                    totalItems: 2
                    totalPages: 1
                    hasPreviousPage: false
                    hasNextPage: true
        "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:
        - Book
      summary: Create Book
      description: Create a book
      x-eventcatalog-message-type: command
      operationId: CreateBookEndpoint
      security:
        - OAuth:
            - catalog
      requestBody:
        description: The command to create a book
        content:
          multipart/form-data:
            schema:
              required:
                - Name
                - Price
                - CategoryId
                - PublisherId
                - AuthorIds
              type: object
              allOf:
                - type: object
                  properties:
                    Name:
                      type: string
                      description: The name of the book
                      example: "Software Architecture: The Hard Parts"
                      maxLength: 50
                - type: object
                  properties:
                    Description:
                      type: string
                      description: The description of the book
                      example: "When two of your authors, Neal and Mark, were writing the book Fundamentals of Software Architecture, we kept coming across complex examples in architecture that we wanted to cover but that were too difficult."
                      maxLength: 500
                - type: object
                  properties:
                    Image:
                      "$ref": "#/components/schemas/IFormFile"
                      description: The image of the book
                - type: object
                  properties:
                    Price:
                      type: number
                      format: double
                      description: The price of the book
                      example: 43.99
                      minimum: 0
                - type: object
                  properties:
                    PriceSale:
                      type: number
                      format: double
                      description: The sale price of the book
                      example: 39.86
                      minimum: 0
                      maximum: 100
                - type: object
                  properties:
                    CategoryId:
                      type: string
                      format: uuid
                      description: The category of the book
                      example: "01961eb2-5a5b-749f-b494-1063d73c96a3"
                - type: object
                  properties:
                    PublisherId:
                      type: string
                      format: uuid
                      description: The publisher of the book
                      example: "01961eb7-be10-7235-bed8-2fea41c28c02"
                - type: object
                  properties:
                    AuthorIds:
                      type: array
                      items:
                        type: string
                        format: uuid
                      description: The authors of the book
                      example:
                        - "01961eb4-0c29-799f-ab78-ad3e2beaa54a"
                        - "01961ebd-2bc1-7de2-aa90-639662d9259e"
            example:
              Name: "Software Architecture: The Hard Parts"
              Description: "When two of your authors, Neal and Mark, were writing the book Fundamentals of Software Architecture, we kept coming across complex examples in architecture that we wanted to cover but that were too difficult."
              Image: "https://default.blob.core.windows.net/catalog/01961eb4-668d-7e7e-ae25-0fab379614f7-software-architecture-the-hard-parts.jpg?sv=2023-01-01&sr=b&st=2023-01-01T00%3A00%3A00Z&se=2023-01-01T01%3A00%3A00Z&sp=r&sig=XXXXX"
              Price: 43.99
              PriceSale: 39.86
              CategoryId: "01961eb2-5a5b-749f-b494-1063d73c96a3"
              PublisherId: "01961eb7-be10-7235-bed8-2fea41c28c02"
              AuthorIds:
                - "01961eb4-0c29-799f-ab78-ad3e2beaa54a"
                - "01961ebd-2bc1-7de2-aa90-639662d9259e"
        required: true
      responses:
        "201":
          description: Created
          content:
            application/json:
              schema:
                type: string
                format: uuid
                description: The unique identifier of the book
                example: "01961eb4-668d-7e7e-ae25-0fab379614f7"
        "400":
          description: Bad Request
          content:
            application/problem+json:
              schema:
                "$ref": "#/components/schemas/HttpValidationProblemDetails"
              examples:
                invalid-name:
                  summary: Invalid 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: "Name"
                        errorMessage: "'Name' must not be empty."
                        severity: 0
                invalid-price:
                  summary: Invalid price
                  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: "Price"
                        errorMessage: "'Price' must be greater than 0."
                        severity: 0
        "401":
          description: Unauthorized - Access token is missing or invalid.
        "403":
          description: Forbidden - The permission requirements are not met.
  "/api/v1/books/{id}":
    get:
      tags:
        - Book
      summary: Get Book
      description: Get a book by identifier
      x-eventcatalog-message-type: query
      operationId: GetBookEndpoint
      parameters:
        - name: id
          in: path
          description: The unique identifier of the book to be retrieved
          required: true
          schema:
            type: string
            format: uuid
            description: The unique identifier of the book to be retrieved
            example: "01961eb4-668d-7e7e-ae25-0fab379614f7"
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/BookDto"
              example:
                id: "01961eb4-668d-7e7e-ae25-0fab379614f7"
                name: "Software Architecture: The Hard Parts"
                description: "When two of your authors, Neal and Mark, were writing the book Fundamentals of Software Architecture, we kept coming across complex examples in architecture that we wanted to cover but that were too difficult."
                image: "https://default.blob.core.windows.net/catalog/01961eb4-668d-7e7e-ae25-0fab379614f7-software-architecture-the-hard-parts.jpg?sv=2023-01-01&sr=b&st=2023-01-01T00%3A00%3A00Z&se=2023-01-01T01%3A00%3A00Z&sp=r&sig=XXXXX"
                price: 43.99
                priceSale: 39.86
                category:
                  id: "01961eb2-5a5b-749f-b494-1063d73c96a3"
                  name: "Programming"
                publisher:
                  id: "01961eb7-be10-7235-bed8-2fea41c28c02"
                  name: "O'Reilly Media, Inc."
                authors:
                  - id: "01961eb4-0c29-799f-ab78-ad3e2beaa54a"
                    name: "Neal Ford"
                  - id: "01961ebd-2bc1-7de2-aa90-639662d9259e"
                    name: "Mark Richards"
                averageRating: 4.5
                totalReviews: 591
        "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"
              example:
                type: "https://tools.ietf.org/html/rfc9110#section-15.5.1"
                title: "Not Found"
                status: 404
                detail: "Book with id 01961eb4-668d-7e7e-ae25-0fab379614f7 not found."
    delete:
      tags:
        - Book
      summary: Delete Book
      description: Delete a book if it exists
      x-eventcatalog-message-type: command
      operationId: DeleteBookEndpoint
      security:
        - OAuth:
            - catalog
      parameters:
        - name: id
          in: path
          description: The unique identifier of the book to be deleted
          required: true
          schema:
            type: string
            format: uuid
            description: The unique identifier of the book 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"
              example:
                type: "https://tools.ietf.org/html/rfc9110#section-15.5.1"
                title: "Not Found"
                status: 404
                detail: "Book with id 01961eb4-668d-7e7e-ae25-0fab379614f7 not found."
  "/grpc/v1/books/{id}":
    get:
      tags:
        - Book gRPC
      summary: Get Book (gRPC)
      description: Get a book by identifier using gRPC service
      x-eventcatalog-message-type: query
      x-grpc-service: BookGrpcService
      x-grpc-method: GetBook
      operationId: GetBookGrpcEndpoint
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
          description: The unique identifier of the book
      responses:
        "200":
          description: Book details retrieved successfully
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/BookGrpcResponse"
        "404":
          description: Book not found
          content:
            application/json:
              schema:
                type: object
                properties:
                  id:
                    type: string
                    example: ""
                  name:
                    type: string
                    example: ""
  "/grpc/v1/books/batch":
    post:
      tags:
        - Book gRPC
      summary: Get Books Batch (gRPC)
      description: Get multiple books by their identifiers using gRPC service
      x-eventcatalog-message-type: query
      x-grpc-service: BookGrpcService
      x-grpc-method: GetBooks
      operationId: GetBooksGrpcEndpoint
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/BooksGrpcRequest"
      responses:
        "200":
          description: Books retrieved successfully
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/BooksGrpcResponse"
  "/api/v1/authors":
    put:
      tags:
        - Author
      summary: Update Author
      description: Update an author if it exists
      operationId: UpdateAuthorEndpoint
      security:
        - OAuth:
            - catalog
      requestBody:
        description: The command to update the author
        content:
          application/json:
            schema:
              "$ref": "#/components/schemas/UpdateAuthorCommand"
            example:
              id: "01961eb4-0c29-799f-ab78-ad3e2beaa54a"
              name: "Neal Ford"
        required: true
      responses:
        "204":
          description: No Content
        "400":
          description: Bad Request
          content:
            application/problem+json:
              schema:
                "$ref": "#/components/schemas/HttpValidationProblemDetails"
              examples:
                invalid-name:
                  summary: Invalid 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: "Name"
                        errorMessage: "'Name' must not be empty."
                        severity: 0
        "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"
              example:
                type: "https://tools.ietf.org/html/rfc9110#section-15.5.1"
                title: "Not Found"
                status: 404
                detail: "Author with id 01961eb4-0c29-799f-ab78-ad3e2beaa54a not found."
    get:
      tags:
        - Author
      summary: List Authors
      description: List all authors
      x-eventcatalog-message-type: query
      operationId: ListAuthorsEndpoint
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: array
                items:
                  "$ref": "#/components/schemas/AuthorDto"
              examples:
                authors-empty:
                  summary: No authors found
                  value: []
                authors-single:
                  summary: Single author
                  value:
                    - id: "01961eb4-0c29-799f-ab78-ad3e2beaa54a"
                      name: "Neal Ford"
                authors-multiple:
                  summary: Multiple authors
                  value:
                    - id: "01961eb4-0c29-799f-ab78-ad3e2beaa54a"
                      name: "Neal Ford"
                    - id: "01961ebd-2bc1-7de2-aa90-639662d9259e"
                      name: "Mark Richards"
    post:
      tags:
        - Author
      summary: Create Author
      description: Create a new author in the catalog system
      x-eventcatalog-message-type: command
      operationId: CreateAuthorEndpoint
      security:
        - OAuth:
            - catalog
      requestBody:
        description: The command to create an author
        content:
          application/json:
            schema:
              "$ref": "#/components/schemas/CreateAuthorCommand"
            example:
              name: "Neal Ford"
        required: true
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: string
                format: uuid
                description: The unique identifier of the author
                example: "01961eb4-0c29-799f-ab78-ad3e2beaa54a"
        "400":
          description: Bad Request
          content:
            application/problem+json:
              schema:
                "$ref": "#/components/schemas/HttpValidationProblemDetails"
              examples:
                empty-name:
                  summary: Empty 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: "Name"
                        errorMessage: "'Name' must not be empty."
                        severity: 0
                name-too-long:
                  summary: Name too long
                  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: "Name"
                        errorMessage: "'Name' must be at most 50 characters."
                        severity: 0
        "401":
          description: Unauthorized - Access token is missing or invalid.
        "403":
          description: Forbidden - The permission requirements are not met.
  "/api/v1/authors/{id}":
    delete:
      tags:
        - Author
      summary: Delete Author
      description: Delete an author from the catalog system
      x-eventcatalog-message-type: command
      operationId: DeleteAuthorEndpoint
      security:
        - OAuth:
            - catalog
      parameters:
        - name: id
          in: path
          description: The unique identifier of the author to be deleted
          required: true
          schema:
            type: string
            format: uuid
            description: The unique identifier of the author to be deleted
            example: "01961eb4-0c29-799f-ab78-ad3e2beaa54a"
      responses:
        "204":
          description: No Content
        "400":
          description: Bad Request
          content:
            application/problem+json:
              schema:
                "$ref": "#/components/schemas/HttpValidationProblemDetails"
              example:
                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: "Id"
                    errorMessage: "Author has books and cannot be deleted"
                    severity: 0
        "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"
              example:
                type: "https://tools.ietf.org/html/rfc9110#section-15.5.1"
                title: "Not Found"
                status: 404
                detail: "Author with id 01961eb4-0c29-799f-ab78-ad3e2beaa54a not found."
components:
  schemas:
    AuthorDto:
      type: object
      readOnly: true
      description: The author of the book
      properties:
        id:
          type: string
          format: uuid
          description: The unique identifier of the author
          example: "01961eb4-0c29-799f-ab78-ad3e2beaa54a"
        name:
          type:
            - "string"
            - "null"
          description: The name of the author
          example: "Neal Ford"
    BookDto:
      type: object
      readOnly: true
      description: The book of the catalog
      properties:
        id:
          type: string
          format: uuid
          description: The unique identifier of the book
          example: "01961eb4-668d-7e7e-ae25-0fab379614f7"
        name:
          type:
            - "string"
            - "null"
          description: The name of the book
          example: "Software Architecture: The Hard Parts"
        description:
          type:
            - "string"
            - "null"
          description: The description of the book
          example: "When two of your authors, Neal and Mark, were writing the book Fundamentals of Software Architecture, we kept coming across complex examples in architecture that we wanted to cover but that were too difficult."
        imageUrl:
          type:
            - "string"
            - "null"
          description: The image URL of the book
          example: "https://default.blob.core.windows.net/catalog/01961eb4-668d-7e7e-ae25-0fab379614f7-software-architecture-the-hard-parts.jpg?sv=2023-01-01&sr=b&st=2023-01-01T00%3A00%3A00Z&se=2023-01-01T01%3A00%3A00Z&sp=r&sig=XXXXX"
        price:
          type: number
          format: double
          description: The price of the book
          example: 43.99
        priceSale:
          type:
            - "number"
            - "null"
          format: double
          description: The sale price of the book
          example: 39.86
        status:
          "$ref": "#/components/schemas/Status"
        category:
          "$ref": "#/components/schemas/CategoryDto"
        publisher:
          "$ref": "#/components/schemas/PublisherDto"
        authors:
          type: array
          items:
            "$ref": "#/components/schemas/AuthorDto"
          description: The authors of the book
          example:
            - id: "01961eb4-0c29-799f-ab78-ad3e2beaa54a"
              name: "Neal Ford"
            - id: "01961ebd-2bc1-7de2-aa90-639662d9259e"
              name: "Mark Richards"
            - id: "01961ebd-ba46-75c6-8834-ff51cc0ff650"
              name: "Pramod Sadalage"
            - id: "01961ebe-1001-7cf6-8071-94b6a622e1a4"
              name: "Zhamak Dehghani"
        averageRating:
          type: number
          format: double
          description: The average rating of the book
          example: 4.5
        totalReviews:
          type: integer
          format: int32
          description: The total number of reviews of the book
          example: 591
    CategoryDto:
      type: object
      readOnly: true
      description: The category of the book
      properties:
        id:
          type: string
          format: uuid
          description: The unique identifier of the category
          example: "01961eb2-5a5b-749f-b494-1063d73c96a3"
        name:
          type:
            - "string"
            - "null"
          description: The name of the category
          example: "Technology"
    CreateAuthorCommand:
      required:
        - name
      type: object
      writeOnly: true
      description: The command to create an author
      properties:
        name:
          type: string
          description: The name of the author
          example: "Neal Ford"
          maxLength: 50
    CreateCategoryCommand:
      required:
        - name
      type: object
      writeOnly: true
      description: The command to create a category
      properties:
        name:
          type: string
          description: The name of the category
          example: "Technology"
          maxLength: 50
    CreatePublisherCommand:
      required:
        - name
      type: object
      writeOnly: true
      description: The command to create a publisher
      properties:
        name:
          type: string
          description: The name of the publisher
          example: "O'Reilly Media, Inc."
          maxLength: 50
    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
          items:
            type: object
            properties:
              propertyName:
                type: string
                description: The name of the property that failed validation
                example: "Name"
              errorMessage:
                type: string
                description: The error message describing the validation failure
                example: "'Name' must not be empty."
              attemptedValue:
                type: object
                description: The value that was attempted
              customState:
                type: object
                description: Custom state information
              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
    IFormFile:
      type: string
      description: The file to be uploaded
    PagedResultOfBookDto:
      required:
        - items
        - pageIndex
        - pageSize
        - totalItems
        - totalPages
      type: object
      readOnly: true
      description: The paged result of books
      properties:
        items:
          type: array
          items:
            "$ref": "#/components/schemas/BookDto"
        pageIndex:
          type: integer
          format: int32
          description: The index of the page
          example: 1
        pageSize:
          type: integer
          format: int32
          description: The size of the page
          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 the page has a previous page
          example: true
        hasNextPage:
          type: boolean
          description: Whether the page has a next page
          example: true
    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: "Category with id 01961eb4-668d-7e7e-ae25-0fab379614f7 not found."
    PublisherDto:
      type: object
      readOnly: true
      description: The publisher of the book
      properties:
        id:
          type: string
          format: uuid
          description: The unique identifier of the publisher
          example: "01961eb7-be10-7235-bed8-2fea41c28c02"
        name:
          type:
            - "string"
            - "null"
          example: "O'Reilly Media, Inc."
    Status:
      type: string
      description: The status of the book
      enum:
        - InStock
        - OutOfStock
      x-enum-descriptions:
        InStock: The book is available for purchase
        OutOfStock: The book is currently not available
    UpdateAuthorCommand:
      required:
        - id
        - name
      type: object
      writeOnly: true
      description: The command to update an author
      properties:
        id:
          type: string
          format: uuid
          description: The unique identifier of the author
          example: "01961eb4-0c29-799f-ab78-ad3e2beaa54a"
        name:
          type: string
          description: The name of the author
          example: "Neal Ford"
          maxLength: 50
    UpdateCategoryCommand:
      required:
        - id
        - name
      type: object
      writeOnly: true
      description: The command to update a category
      properties:
        id:
          type: string
          format: uuid
          description: The unique identifier of the category
          example: "01961eb2-5a5b-749f-b494-1063d73c96a3"
        name:
          type: string
          description: The name of the category
          example: "Technology"
          maxLength: 50
    UpdatePublisherCommand:
      required:
        - id
        - name
      type: object
      writeOnly: true
      description: The command to update a publisher
      properties:
        id:
          type: string
          format: uuid
          description: The unique identifier of the publisher
          example: "01961eb7-be10-7235-bed8-2fea41c28c02"
        name:
          type: string
          description: The name of the publisher
          example: "O'Reilly Media, Inc."
          maxLength: 50
    BooksGrpcRequest:
      type: object
      description: Request for getting multiple books via gRPC
      properties:
        bookIds:
          type: array
          items:
            type: string
            format: uuid
          description: Array of book unique identifiers
          example:
            [
              "01961eb4-668d-7e7e-ae25-0fab379614f7",
              "01961eb4-0c29-799f-ab78-ad3e2beaa54a",
            ]
      required:
        - bookIds
    BookGrpcResponse:
      type: object
      description: gRPC response for a single book
      properties:
        id:
          type: string
          format: uuid
          description: The unique identifier of the book
          example: "01961eb4-668d-7e7e-ae25-0fab379614f7"
        name:
          type: string
          description: The name of the book
          example: "Software Architecture: The Hard Parts"
        price:
          type: number
          format: double
          description: The price of the book
          example: 49.99
        priceSale:
          type: number
          format: double
          nullable: true
          description: The sale price of the book (optional)
          example: 39.99
        status:
          "$ref": "#/components/schemas/BookGrpcStatus"
    BooksGrpcResponse:
      type: object
      description: gRPC response for multiple books
      properties:
        books:
          type: array
          items:
            "$ref": "#/components/schemas/BookGrpcResponse"
          description: Array of book responses
    BookGrpcStatus:
      type: string
      enum:
        - InStock
        - OutOfStock
      description: The availability status of the book
      example: "InStock"
  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:
            catalog: "Catalog API"
          x-usePkce: "SHA-256"
          x-scalar-client-id: "catalog"
          x-scalar-security-body:
            audience: "account"
tags:
  - name: Publisher
    description: Operations related to publishers
  - name: Category
    description: Operations related to categories
  - name: Book
    description: Operations related to books
  - name: Author
    description: Operations related to authors
  - name: Book gRPC
    description: gRPC operations for books
