Open API spec

See Something, Say Something, Albuquerque!

Open API specification of server endpoints

Page contents

Overview

This is the 1st draft of the Open API spec for our server endpoints.

openapi: 3.1.0
info:
  title: See Something ABQ API
  version: 0.3.0-milestone-3-draft
  summary: OpenAPI specification aligned to the current Milestone 3 server controllers.
  description: |
    OpenAPI specification for the current authenticated server-side API.

    Authentication model:
      * All endpoints require a valid JWT bearer token.
      * Manager-only endpoints are documented in each operation description.
      * Manager authorization is enforced server-side from JWT role claims.

servers:
  - url: /api
    description: Application-relative base URL
security:
  - bearerAuth: []
tags:
  - name: Users
    description: Endpoints for the currently authenticated user and manager user administration.
  - name: Issue Reports
    description: Endpoints for creating, reading, updating, deleting, and administrating issue reports.
  - name: Issue Types
    description: Endpoints for listing and managing issue type lookup values.
  - name: Accepted States
    description: Endpoints for managing accepted state lookup values.
  - name: Report Images
    description: Endpoints for adding and retrieving images associated with issue reports.
paths:
  /users/me:
    get:
      tags: [Users]
      summary: Get the current user's profile
      operationId: getCurrentUser
      description: Returns the profile for the authenticated user. The service may create the profile automatically if needed.
      responses:
        '200':
          description: Current user profile retrieved successfully.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UserProfile'
        '401':
          $ref: '#/components/responses/Unauthorized'
    
  /users/me/display-name:
    put:
      tags: [Users]
      summary: Update the current user's display name
      operationId: updateCurrentUserDisplayName
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateDisplayNameRequest'
      responses:
        '200':
          description: User profile updated successfully.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UserProfile'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'

  /users/me/email:
    put:
      tags: [Users]
      summary: Update the current user's email address
      operationId: updateCurrentUserEmail
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateEmailRequest'
      responses:
        '200':
          description: User profile updated successfully.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UserProfile'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'

  /users/me/avatar:
    put:
      tags: [Users]
      summary: Update the current user's avatar URL
      operationId: updateCurrentUserAvatar
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateAvatarRequest'
      responses:
        '200':
          description: User profile updated successfully.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UserProfile'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'

  /manager/users:
    get:
      tags: [Users]
      summary: Get all user profiles
      operationId: managerGetUsers
      description: Manager role required. Returns all user profiles.
      responses:
        '200':
          description: User profiles retrieved successfully.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/UserProfile'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'

  /manager/users/{externalId}:
    parameters:
      - $ref: '#/components/parameters/ExternalId'
    get:
      tags: [Users]
      summary: Get a user profile by external ID
      operationId: managerGetUserByExternalId
      description: Manager role required.
      responses:
        '200':
          description: User profile retrieved successfully.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UserProfile'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'

  /manager/users/{externalId}/manager-status:
    parameters:
      - $ref: '#/components/parameters/ExternalId'
    patch:
      tags: [Users]
      summary: Update a user's manager status
      operationId: managerUpdateUserManagerStatus
      description: Manager role required.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ManagerStatusUpdateRequest'
      responses:
        '200':
          description: User profile updated successfully.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UserProfile'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'

  /manager/users/{externalId}/enabled:
    parameters:
      - $ref: '#/components/parameters/ExternalId'
    patch:
      tags: [Users]
      summary: Update a user's enabled status
      operationId: managerUpdateUserEnabled
      description: Manager role required.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UserEnabledUpdateRequest'
      responses:
        '200':
          description: User profile updated successfully.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UserProfile'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'

  /issue-reports/mine:
    get:
      tags: [Issue Reports]
      summary: Get the authenticated user's issue reports
      operationId: getMyIssueReports
      parameters:
        - name: sort
          in: query
          required: false
          description: |
            Sort selector for the current user's issue reports.

            Supported field keys:
            - `last_modified`
            - `first_reported`

            Supported formats:
            - `last_modified`
            - `last_modified,asc`
            - `last_modified,desc`
            - `first_reported,asc`
            - `first_reported,desc`
            - multiple clauses separated by semicolons, for example
              `last_modified,desc;first_reported,desc`

            Unknown field keys are ignored. If no valid clauses are provided,
            results default to `last_modified` descending.
          schema:
            type: string
            default: last_modified
            example: last_modified,desc;first_reported,desc
      responses:
        '200':
          description: Issue report summaries retrieved successfully.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/IssueReportSummary'
        '401':
          $ref: '#/components/responses/Unauthorized'

  /issue-reports:
    post:
      tags: [Issue Reports]
      summary: Create an issue report
      operationId: createIssueReport
      description: Creates an issue report for the authenticated user. The server derives ownership from the authenticated principal and sets the default accepted state internally.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/IssueReportWriteRequest'
      responses:
        '201':
          description: Issue report created successfully.
          headers:
            Location:
              description: Relative URL of the created issue report resource.
              schema:
                type: string
                format: uri-reference
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/IssueReport'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '500':
          $ref: '#/components/responses/InternalServerError'

  /issue-reports/{externalKey}:
    parameters:
      - $ref: '#/components/parameters/ExternalKey'
    get:
      tags: [Issue Reports]
      summary: Get an issue report by external key
      operationId: getIssueReportByExternalKey
      responses:
        '200':
          description: Issue report retrieved successfully.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/IssueReport'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/NotFound'
    put:
      tags: [Issue Reports]
      summary: Update an issue report by external key
      operationId: updateIssueReport
      description: Updates user-editable fields on an existing issue report.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/IssueReportWriteRequest'
      responses:
        '200':
          description: Issue report updated successfully.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/IssueReport'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/NotFound'
    delete:
      tags: [Issue Reports]
      summary: Delete an issue report by external key
      operationId: deleteIssueReport
      responses:
        '204':
          description: Issue report deleted successfully.
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/NotFound'

  /manager/issue-reports:
    get:
      tags: [Issue Reports]
      summary: Get paged issue reports for manager review
      operationId: managerGetIssueReports
      description: Manager role required. Returns issue reports in a paged response ordered by timeLastModified descending.
      parameters:
        - name: pageSize
          in: query
          required: false
          schema:
            type: integer
            default: 20
            minimum: 1
        - name: pageNumber
          in: query
          required: false
          schema:
            type: integer
            default: 0
            minimum: 0
      responses:
        '200':
          description: Paged issue reports retrieved successfully.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ManagerIssueReportPage'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'

  /manager/issue-reports/{externalId}/status:
    parameters:
      - $ref: '#/components/parameters/ExternalId'
    put:
      tags: [Issue Reports]
      summary: Update an issue report's accepted state
      operationId: managerUpdateIssueReportStatus
      description: Manager role required.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/IssueReportStatusUpdateRequest'
      responses:
        '200':
          description: Issue report updated successfully.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/IssueReport'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'

  /manager/issue-reports/{externalId}/issue-types:
    parameters:
      - $ref: '#/components/parameters/ExternalId'
    put:
      tags: [Issue Reports]
      summary: Replace an issue report's issue types
      operationId: managerUpdateIssueReportTypes
      description: Manager role required. Replaces the entire issue type set for the specified issue report.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/IssueReportTypesUpdateRequest'
      responses:
        '200':
          description: Issue report updated successfully.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/IssueReport'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'

  /issue-types:
    get:
      tags: [Issue Types]
      summary: Get all issue types
      operationId: getIssueTypes
      responses:
        '200':
          description: Issue types retrieved successfully.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/IssueType'
        '401':
          $ref: '#/components/responses/Unauthorized'

  /manager/issue-types:
    post:
      tags: [Issue Types]
      summary: Create an issue type
      operationId: managerCreateIssueType
      description: Manager role required.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/IssueType'
      responses:
        '200':
          description: Issue type created successfully.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/IssueType'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '409':
          $ref: '#/components/responses/Conflict'

  /manager/issue-types/{issueTypeTag}:
    parameters:
      - $ref: '#/components/parameters/IssueTypeTag'
    patch:
      tags: [Issue Types]
      summary: Update an issue type description
      operationId: managerUpdateIssueTypeDescription
      description: Manager role required. The current implementation expects the request body to be a raw JSON string containing the new description.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: string
              description: New issue type description encoded as a JSON string value.
              example: Illegal dumping or trash accumulation
      responses:
        '200':
          description: Issue type updated successfully.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/IssueType'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
    delete:
      tags: [Issue Types]
      summary: Delete an unused issue type
      operationId: managerDeleteIssueType
      description: Manager role required. Deletion succeeds only when no issue reports reference the issue type.
      responses:
        '204':
          description: Issue type deleted successfully.
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'

  /manager/accepted-states:
    get:
      tags: [Accepted States]
      summary: Get all accepted states
      operationId: managerGetAcceptedStates
      description: Manager role required.
      responses:
        '200':
          description: Accepted states retrieved successfully.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/AcceptedState'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
    post:
      tags: [Accepted States]
      summary: Create an accepted state
      operationId: managerCreateAcceptedState
      description: Manager role required.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AcceptedState'
      responses:
        '200':
          description: Accepted state created successfully.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AcceptedState'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '409':
          $ref: '#/components/responses/Conflict'

  /manager/accepted-states/{statusTag}:
    parameters:
      - $ref: '#/components/parameters/StatusTag'
    patch:
      tags: [Accepted States]
      summary: Update an accepted state description
      operationId: managerUpdateAcceptedStateDescription
      description: Manager role required.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AcceptedStateDescriptionUpdateRequest'
      responses:
        '200':
          description: Accepted state updated successfully.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AcceptedState'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
    delete:
      tags: [Accepted States]
      summary: Delete an unused accepted state
      operationId: managerDeleteAcceptedState
      description: Manager role required. Deletion succeeds only when no issue reports reference the accepted state.
      responses:
        '204':
          description: Accepted state deleted successfully.
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'

  /issue-reports/{externalKey}/images:
    parameters:
      - $ref: '#/components/parameters/ExternalKey'
    post:
      tags: [Report Images]
      summary: Add an image to an issue report
      operationId: addIssueReportImage
      description: Adds an image to the specified issue report. The current implementation only allows the report owner to add images.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AddImageRequest'
      responses:
        '201':
          description: Image added successfully.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ReportImage'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'

  /issue-reports/{externalKey}/images/{imageKey}:
    parameters:
      - $ref: '#/components/parameters/ExternalKey'
      - $ref: '#/components/parameters/ImageKey'
    get:
      tags: [Report Images]
      summary: Get an image associated with an issue report
      operationId: getIssueReportImage
      description: Returns a specific report image. The current implementation allows access to the report owner and managers.
      responses:
        '200':
          description: Image retrieved successfully.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ReportImage'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'

components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: JWT bearer token validated by the Spring resource server.

  parameters:
    ExternalId:
      name: externalId
      in: path
      required: true
      description: UUID external identifier.
      schema:
        type: string
        format: uuid
    ExternalKey:
      name: externalKey
      in: path
      required: true
      description: UUID external key.
      schema:
        type: string
        format: uuid
    ImageKey:
      name: imageKey
      in: path
      required: true
      description: UUID external key for a report image.
      schema:
        type: string
        format: uuid
    IssueTypeTag:
      name: issueTypeTag
      in: path
      required: true
      schema:
        type: string
    StatusTag:
      name: statusTag
      in: path
      required: true
      schema:
        type: string

  responses:
    BadRequest:
      description: The request body or parameters were invalid.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    Unauthorized:
      description: Authentication is required or the bearer token was invalid.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    Forbidden:
      description: The authenticated user does not have permission to perform this operation.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    NotFound:
      description: The requested resource was not found.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    Conflict:
      description: The operation could not be completed because of a uniqueness or in-use conflict.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    InternalServerError:
      description: An unexpected server-side error occurred.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'

  schemas:
    ErrorResponse:
      type: object
      description: Generic error response schema used while exception handling is being standardized.
      properties:
        message:
          type: string
          description: Human-readable error message.
        status:
          type: integer
          description: HTTP status code when available.
        error:
          type: string
          description: HTTP reason phrase or error category when available.
        timestamp:
          type: string
          format: date-time
          description: Error timestamp when provided by the runtime.
        path:
          type: string
          description: Request path when provided by the runtime.

    UserProfile:
      type: object
      required: [externalId, displayName, email, isManager, timeCreated, userEnabled]
      properties:
        externalId:
          type: string
          format: uuid
        displayName:
          type: string
        email:
          type: string
        avatar:
          type: string
          format: uri
          nullable: true
        isManager:
          type: boolean
        timeCreated:
          type: string
          format: date-time
        userEnabled:
          type: boolean

    UpdateDisplayNameRequest:
      type: object
      required: [displayName]
      properties:
        displayName:
          type: string

    UpdateEmailRequest:
      type: object
      required: [email]
      properties:
        email:
          type: string

    UpdateAvatarRequest:
      type: object
      required: [avatar]
      properties:
        avatar:
          type: string
          format: uri

    ManagerStatusUpdateRequest:
      type: object
      required: [manager]
      properties:
        manager:
          type: boolean

    UserEnabledUpdateRequest:
      type: object
      required: [enabled]
      properties:
        enabled:
          type: boolean

    ReportLocation:
      type: object
      properties:
        latitude:
          type: number
          format: double
          nullable: true
        longitude:
          type: number
          format: double
          nullable: true
        streetCoordinate:
          type: string
          nullable: true
        locationDescription:
          type: string
          nullable: true

    AcceptedState:
      type: object
      required: [statusTag, statusTagDescription]
      properties:
        statusTag:
          type: string
        statusTagDescription:
          type: string

    IssueType:
      type: object
      required: [issueTypeTag, issueTypeDescription]
      properties:
        issueTypeTag:
          type: string
        issueTypeDescription:
          type: string

    ReportImage:
      type: object
      required: [externalKey, imageLocator, filename, mimeType, albumOrder]
      properties:
        externalKey:
          type: string
          format: uuid
        imageLocator:
          type: string
          format: uri
        filename:
          type: string
        mimeType:
          type: string
        albumOrder:
          type: integer

    AddImageRequest:
      type: object
      required: [imageLocator, filename, mimeType, albumOrder]
      properties:
        imageLocator:
          type: string
          format: uri
        filename:
          type: string
        mimeType:
          type: string
        albumOrder:
          type: integer

    IssueReport:
      type: object
      required:
        - externalId
        - userProfile
        - reportLocation
        - acceptedState
        - issueTypes
        - timeFirstReported
        - timeLastModified
        - textDescription
        - reportImages
      properties:
        externalId:
          type: string
          format: uuid
        userProfile:
          $ref: '#/components/schemas/UserProfile'
        reportLocation:
          $ref: '#/components/schemas/ReportLocation'
        acceptedState:
          $ref: '#/components/schemas/AcceptedState'
        issueTypes:
          type: array
          items:
            $ref: '#/components/schemas/IssueType'
        timeFirstReported:
          type: string
          format: date-time
        timeLastModified:
          type: string
          format: date-time
        textDescription:
          type: string
        reportImages:
          type: array
          items:
            $ref: '#/components/schemas/ReportImage'

    IssueReportWriteRequest:
      type: object
      required: [reportLocation, textDescription]
      properties:
        reportLocation:
          $ref: '#/components/schemas/ReportLocation'
        issueTypes:
          type: array
          description: Present in the current entity shape, but manager update endpoints are the documented mechanism for replacing issue types.
          items:
            $ref: '#/components/schemas/IssueType'
        textDescription:
          type: string
        reportImages:
          type: array
          description: Present in the current entity shape, but image creation is handled through the dedicated image endpoint.
          items:
            $ref: '#/components/schemas/ReportImage'

    IssueReportSummary:
      type: object
      required:
        - externalId
        - description
        - acceptedState
        - timeFirstReported
        - timeLastModified
      properties:
        externalId:
          type: string
          format: uuid
        description:
          type: string
        acceptedState:
          type: string
        timeFirstReported:
          type: string
          format: date-time
        timeLastModified:
          type: string
          format: date-time

    IssueReportStatusUpdateRequest:
      type: object
      required: [statusTag]
      properties:
        statusTag:
          type: string

    IssueReportTypesUpdateRequest:
      type: object
      required: [issueTypeTags]
      properties:
        issueTypeTags:
          type: array
          items:
            type: string

    AcceptedStateDescriptionUpdateRequest:
      type: object
      required: [statusTagDescription]
      properties:
        statusTagDescription:
          type: string

    ManagerIssueReportResponse:
      type: object
      required:
        - externalId
        - userProfile
        - reportLocation
        - acceptedState
        - issueTypes
        - timeFirstReported
        - timeLastModified
        - textDescription
        - reportImages
      properties:
        externalId:
          type: string
          format: uuid
        userProfile:
          $ref: '#/components/schemas/UserProfile'
        reportLocation:
          $ref: '#/components/schemas/ReportLocation'
        acceptedState:
          $ref: '#/components/schemas/AcceptedState'
        issueTypes:
          type: array
          items:
            $ref: '#/components/schemas/IssueType'
        timeFirstReported:
          type: string
          format: date-time
        timeLastModified:
          type: string
          format: date-time
        textDescription:
          type: string
        reportImages:
          type: array
          items:
            $ref: '#/components/schemas/ReportImage'

    ManagerIssueReportPage:
      type: object
      description: Spring Data Page response for manager issue report listings.
      properties:
        content:
          type: array
          items:
            $ref: '#/components/schemas/ManagerIssueReportResponse'
        pageable:
          type: object
          additionalProperties: true
        last:
          type: boolean
        totalElements:
          type: integer
          format: int64
        totalPages:
          type: integer
        size:
          type: integer
        number:
          type: integer
        sort:
          type: object
          additionalProperties: true
        first:
          type: boolean
        numberOfElements:
          type: integer
        empty:
          type: boolean