# Copyright (c) Abstract Machines
# SPDX-License-Identified: Apache-2.0

openapi: 3.0.3
info:
  title: SuperMQ Domains Service
  description: |
    This is the Domains Server based on the OpenAPI 3.0 specification.  It is the HTTP API for managing platform domains. You can now help us improve the API whether it's by making changes to the definition itself or to the code.
    Some useful links:
    - [The SuperMQ repository](https://github.com/absmach/supermq)
  contact:
    email: info@abstractmachines.fr
  license:
    name: Apache 2.0
    url: https://github.com/absmach/supermq/blob/main/LICENSE
  version: 0.18.0

servers:
  - url: http://localhost:9003
  - url: https://localhost:9003

tags:
  - name: Domains
    description: CRUD operations for your domains
    externalDocs:
      description: Find out more about domains
      url: https://docs.magistrala.abstractmachines.fr/
  - name: Roles
    description: All operations involving roles for domains
    externalDocs:
      description: Find out more about roles
      url: https://docs.supermq.abstractmachines.fr/
  - name: Invitations
    description: All operations involving invitations for domains
    externalDocs:
      description: Find out more about Invitations
      url: https://docs.supermq.abstractmachines.fr/
  - name: Health
    description: Service health check endpoint.
    externalDocs:
      description: Find out more about health check
      url: https://docs.magistrala.abstractmachines.fr/

paths:
  /domains:
    post:
      tags:
        - Domains
      summary: Adds new domain
      description: |
        Adds new domain.
      requestBody:
        $ref: "#/components/requestBodies/DomainCreateReq"
      responses:
        "201":
          $ref: "#/components/responses/DomainCreateRes"
        "400":
          description: Failed due to malformed JSON.
        "401":
          description: Missing or invalid access token provided.
        "409":
          description: Failed due to using an existing route.
        "415":
          description: Missing or invalid content type.
        "422":
          description: Database can't process request.
        "500":
          $ref: "#/components/responses/ServiceError"
    get:
      summary: Retrieves list of domains.
      description: |
        Retrieves list of domains that the user have access.
      parameters:
        - $ref: "#/components/parameters/Limit"
        - $ref: "#/components/parameters/Offset"
        - $ref: "#/components/parameters/Metadata"
        - $ref: "#/components/parameters/Status"
        - $ref: "#/components/parameters/DomainName"
        - $ref: "#/components/parameters/Permission"
      tags:
        - Domains
      security:
        - bearerAuth: []
      responses:
        "200":
          $ref: "#/components/responses/DomainsPageRes"
        "400":
          description: Failed due to malformed query parameters.
        "401":
          description: Missing or invalid access token provided.
        "404":
          description: A non-existent entity request.
        "422":
          description: Database can't process request.
        "500":
          $ref: "#/components/responses/ServiceError"

  /domains/{domainID}:
    get:
      summary: Retrieves domain information
      description: |
        Retrieves a specific domain that is identified by the domain ID.
      tags:
        - Domains
      parameters:
        - $ref: "#/components/parameters/DomainID"
      security:
        - bearerAuth: []
      responses:
        "200":
          $ref: "#/components/responses/DomainRes"
        "400":
          description: Failed due to malformed query parameters.
        "401":
          description: Missing or invalid access token provided.
        "403":
          description: Unauthorized access to domain id.
        "404":
          description: A non-existent entity request.
        "422":
          description: Database can't process request.
        "500":
          $ref: "#/components/responses/ServiceError"

    patch:
      summary: Updates name, metadata and tags of the domain.
      description: |
        Updates name, metadata and tags of the domain.
      tags:
        - Domains
      parameters:
        - $ref: "#/components/parameters/DomainID"
      requestBody:
        $ref: "#/components/requestBodies/DomainUpdateReq"
      security:
        - bearerAuth: []
      responses:
        "200":
          $ref: "#/components/responses/DomainRes"
        "400":
          description: Failed due to malformed JSON.
        "401":
          description: Missing or invalid access token provided.
        "403":
          description: Unauthorized access to domain id.
        "404":
          description: Failed due to non existing domain.
        "415":
          description: Missing or invalid content type.
        "500":
          $ref: "#/components/responses/ServiceError"

  /domains/{domainID}/enable:
    post:
      summary: Enables a domain
      description: |
        Enables a specific domain that is identified by the domain ID.
      tags:
        - Domains
      parameters:
        - $ref: "#/components/parameters/DomainID"
      security:
        - bearerAuth: []
      responses:
        "200":
          description: Successfully enabled domain.
        "400":
          description: Failed due to malformed domain's ID.
        "401":
          description: Missing or invalid access token provided.
        "403":
          description: Unauthorized access the domain ID.
        "404":
          description: A non-existent entity request.
        "422":
          description: Database can't process request.
        "500":
          $ref: "#/components/responses/ServiceError"

  /domains/{domainID}/disable:
    post:
      summary: Disable a domain
      description: |
        Disable a specific domain that is identified by the domain ID.
      tags:
        - Domains
      parameters:
        - $ref: "#/components/parameters/DomainID"
      security:
        - bearerAuth: []
      responses:
        "200":
          description: Successfully disabled domain.
        "400":
          description: Failed due to malformed domain's ID.
        "401":
          description: Missing or invalid access token provided.
        "403":
          description: Unauthorized access the domain ID.
        "404":
          description: A non-existent entity request.
        "422":
          description: Database can't process request.
        "500":
          $ref: "#/components/responses/ServiceError"

  /domains/{domainID}/freeze:
    post:
      summary: Freeze a domain
      description: |
        Freeze a specific domain that is identified by the domain ID.
      tags:
        - Domains
      parameters:
        - $ref: "#/components/parameters/DomainID"
      security:
        - bearerAuth: []
      responses:
        "200":
          description: Successfully freezed domain.
        "400":
          description: Failed due to malformed domain's ID.
        "401":
          description: Missing or invalid access token provided.
        "403":
          description: Unauthorized access the domain ID.
        "404":
          description: A non-existent entity request.
        "422":
          description: Database can't process request.
        "500":
          $ref: "#/components/responses/ServiceError"

  /domains/{domainID}/roles:
    post:
      operationId: createDomainRole
      summary: Creates a role for a domain
      description: |
        Creates a role for a specific domain that is identified by the domain ID.
      tags:
        - Roles
      parameters:
        - $ref: "#/components/parameters/DomainID"
      requestBody:
        $ref: "./schemas/roles.yaml#/components/requestBodies/CreateRoleReq"
      security:
        - bearerAuth: []
      responses:
        "201":
          $ref: "./schemas/roles.yaml#/components/responses/CreateRoleRes"
        "400":
          description: Failed due to malformed domain's ID.
        "401":
          description: Missing or invalid access token provided.
        "403":
          description: Failed to perform authorization over the entity.
        "404":
          description: A non-existent entity request.
        "422":
          description: Database can't process request.
        "500":
          $ref: "#/components/responses/ServiceError"

    get:
      operationId: listDomainRoles
      tags:
        - Roles
      summary: Retrieves domains roles.
      description: |
        Retrieves a list of domain roles. Due to performance concerns, data
        is retrieved in subsets. The API domains must ensure that the entire
        dataset is consumed either by making subsequent requests, or by
        increasing the subset size of the initial request.
      parameters:
        - $ref: "#/components/parameters/DomainID"
        - $ref: "#/components/parameters/Limit"
        - $ref: "#/components/parameters/Offset"
      security:
        - bearerAuth: []
      responses:
        "200":
          $ref: "./schemas/roles.yaml#/components/responses/ListRolesRes"
        "400":
          description: Failed due to malformed query parameters.
        "401":
          description: |
            Missing or invalid access token provided.
        "403":
          description: Failed to perform authorization over the entity.
        "404":
          description: A non-existent entity request.
        "422":
          description: Database can't process request.
        "500":
          $ref: "#/components/responses/ServiceError"

  /domains/{domainID}/roles/{roleID}:
    get:
      operationId: getDomainRole
      tags:
        - Roles
      summary: Retrieves domain role.
      description: |
        Retrieves a specific domain role that is identified by the role name.
      parameters:
        - $ref: "#/components/parameters/DomainID"
        - $ref: "./schemas/roles.yaml#/components/parameters/RoleID"
      security:
        - bearerAuth: []
      responses:
        "200":
          $ref: "./schemas/roles.yaml#/components/responses/GetRoleRes"
        "400":
          description: Failed due to malformed query parameters.
        "401":
          description: |
            Missing or invalid access token provided.
        "403":
          description: Failed to perform authorization over the entity.
        "404":
          description: A non-existent entity request.
        "422":
          description: Database can't process request.
        "500":
          $ref: "#/components/responses/ServiceError"

    put:
      operationId: updateDomainRole
      summary: Updates domain role.
      description: |
        Updates a specific domain role that is identified by the role name.
      tags:
        - Roles
      parameters:
        - $ref: "#/components/parameters/DomainID"
        - $ref: "./schemas/roles.yaml#/components/parameters/RoleID"
      requestBody:
        $ref: "./schemas/roles.yaml#/components/requestBodies/UpdateRoleReq"
      security:
        - bearerAuth: []
      responses:
        "200":
          $ref: "./schemas/roles.yaml#/components/responses/GetRoleRes"
        "400":
          description: Failed due to malformed query parameters.
        "401":
          description: |
            Missing or invalid access token provided.
        "403":
          description: Failed to perform authorization over the entity.
        "404":
          description: A non-existent entity request.
        "422":
          description: Database can't process request.
        "500":
          $ref: "#/components/responses/ServiceError"

    delete:
      operationId: deleteDomainRole
      summary: Deletes domain role.
      description: |
        Deletes a specific domain role that is identified by the role name.
      tags:
        - Roles
      parameters:
        - $ref: "#/components/parameters/DomainID"
        - $ref: "./schemas/roles.yaml#/components/parameters/RoleID"
      security:
        - bearerAuth: []
      responses:
        "204":
          description: Role deleted.
        "400":
          description: Failed due to malformed query parameters.
        "401":
          description: |
            Missing or invalid access token provided.
        "403":
          description: Failed to perform authorization over the entity.
        "404":
          description: A non-existent entity request.
        "422":
          description: Database can't process request.
        "500":
          $ref: "#/components/responses/ServiceError"

  /domain/{domainID}/roles/members:
    get:
      operationId: getDomainMembers
      tags:
        - Roles
      summary: Retrieves domain members from all roles.
      description: |
        Retrieves members from role for the specific domain.
      parameters:
        - $ref: "auth.yaml#/components/parameters/DomainID"
      security:
        - bearerAuth: []
      responses:
        "200":
          $ref: "./schemas/roles.yaml#/components/responses/ListEntityMembersRes"
        "400":
          description: Failed due to malformed query parameters.
        "401":
          description: |
            Missing or invalid access token provided.
        "403":
          description: Failed to perform authorization over the entity.
        "404":
          description: A non-existent entity request.
        "422":
          description: Database can't process request.
        "500":
          $ref: "#/components/responses/ServiceError"

  /domains/{domainID}/roles/{roleID}/actions:
    post:
      operationId: addDomainRoleAction
      summary: Adds a role action for a domain role.
      description: |
        Adds a role action for a specific domain role that is identified by the role name.
      tags:
        - Roles
      parameters:
        - $ref: "#/components/parameters/DomainID"
        - $ref: "./schemas/roles.yaml#/components/parameters/RoleID"
      requestBody:
        $ref: "./schemas/roles.yaml#/components/requestBodies/AddRoleActionsReq"
      security:
        - bearerAuth: []
      responses:
        "200":
          $ref: "./schemas/roles.yaml#/components/responses/AddRoleActionsRes"
        "400":
          description: Failed due to malformed query parameters.
        "401":
          description: |
            Missing or invalid access token provided.
        "403":
          description: Failed to perform authorization over the entity.
        "404":
          description: A non-existent entity request.
        "422":
          description: Database can't process request.
        "500":
          $ref: "#/components/responses/ServiceError"

    get:
      operationId: listDomainRoleActions
      tags:
        - Roles
      summary: Lists domain role actions.
      description: |
        Retrieves a list of domain role actions.
      parameters:
        - $ref: "#/components/parameters/DomainID"
        - $ref: "./schemas/roles.yaml#/components/parameters/RoleID"
      security:
        - bearerAuth: []
      responses:
        "200":
          $ref: "./schemas/roles.yaml#/components/responses/ListRoleActionsRes"
        "400":
          description: Failed due to malformed query parameters.
        "401":
          description: |
            Missing or invalid access token provided.
        "403":
          description: Failed to perform authorization over the entity.
        "404":
          description: A non-existent entity request.
        "422":
          description: Database can't process request.
        "500":
          $ref: "#/components/responses/ServiceError"

  /domains/{domainID}/roles/{roleID}/actions/delete:
    post:
      operationId: deleteDomainRoleAction
      summary: Deletes role actions for a domain role.
      description: |
        Deletes a role action for a specific domain role that is identified by the role name.
      tags:
        - Roles
      parameters:
        - $ref: "#/components/parameters/DomainID"
        - $ref: "./schemas/roles.yaml#/components/parameters/RoleID"
      requestBody:
        $ref: "./schemas/roles.yaml#/components/requestBodies/AddRoleActionsReq"
      security:
        - bearerAuth: []
      responses:
        "204":
          description: Role actions deleted.
        "400":
          description: Failed due to malformed query parameters.
        "401":
          description: |
            Missing or invalid access token provided.
        "403":
          description: Failed to perform authorization over the entity.
        "404":
          description: A non-existent entity request.
        "422":
          description: Database can't process request.
        "500":
          $ref: "#/components/responses/ServiceError"

  /domains/{domainID}/roles/{roleID}/actions/delete-all:
    post:
      operationId: deleteAllDomainRoleActions
      summary: Deletes all role actions for a domain role.
      description: |
        Deletes all role actions for a specific domain role that is identified by the role name.
      tags:
        - Roles
      parameters:
        - $ref: "#/components/parameters/DomainID"
        - $ref: "./schemas/roles.yaml#/components/parameters/RoleID"
      security:
        - bearerAuth: []
      responses:
        "204":
          description: All role actions deleted.
        "400":
          description: Failed due to malformed query parameters.
        "401":
          description: |
            Missing or invalid access token provided.
        "403":
          description: Failed to perform authorization over the entity.
        "404":
          description: A non-existent entity request.
        "422":
          description: Database can't process request.
        "500":
          $ref: "#/components/responses/ServiceError"

  /domains/{domainID}/roles/{roleID}/members:
    post:
      operationId: addDomainRoleMember
      summary: Adds a member to a domain role.
      description: |
        Adds a member to a specific domain role that is identified by the role name.
      tags:
        - Roles
      parameters:
        - $ref: "#/components/parameters/DomainID"
        - $ref: "./schemas/roles.yaml#/components/parameters/RoleID"
      requestBody:
        $ref: "./schemas/roles.yaml#/components/requestBodies/AddRoleMembersReq"
      security:
        - bearerAuth: []
      responses:
        "200":
          $ref: "./schemas/roles.yaml#/components/responses/AddRoleMembersRes"
        "400":
          description: Failed due to malformed query parameters.
        "401":
          description: |
            Missing or invalid access token provided.
        "403":
          description: Failed to perform authorization over the entity.
        "404":
          description: A non-existent entity request.
        "422":
          description: Database can't process request.
        "500":
          $ref: "#/components/responses/ServiceError"

    get:
      operationId: listDomainRoleMembers
      tags:
        - Roles
      summary: Lists domain role members.
      description: |
        Retrieves a list of domain role members.
      parameters:
        - $ref: "#/components/parameters/DomainID"
        - $ref: "./schemas/roles.yaml#/components/parameters/RoleID"
      security:
        - bearerAuth: []
      responses:
        "200":
          $ref: "./schemas/roles.yaml#/components/responses/ListRoleMembersRes"
        "400":
          description: Failed due to malformed query parameters.
        "401":
          description: |
            Missing or invalid access token provided.
        "403":
          description: Failed to perform authorization over the entity.
        "404":
          description: A non-existent entity request.
        "422":
          description: Database can't process request.
        "500":
          $ref: "#/components/responses/ServiceError"

  /domains/{domainID}/roles/{roleID}/members/delete:
    post:
      operationId: deleteDomainRoleMembers
      summary: Deletes members from a domain role.
      description: |
        Deletes a member from a specific domain role that is identified by the role name.
      tags:
        - Roles
      parameters:
        - $ref: "#/components/parameters/DomainID"
        - $ref: "./schemas/roles.yaml#/components/parameters/RoleID"
      requestBody:
        $ref: "./schemas/roles.yaml#/components/requestBodies/AddRoleMembersReq"
      security:
        - bearerAuth: []
      responses:
        "204":
          description: Role members deleted.
        "400":
          description: Failed due to malformed query parameters.
        "401":
          description: |
            Missing or invalid access token provided.
        "403":
          description: Failed to perform authorization over the entity.
        "404":
          description: A non-existent entity request.
        "422":
          description: Database can't process request.
        "500":
          $ref: "#/components/responses/ServiceError"

  /domains/{domainID}/roles/{roleID}/members/delete-all:
    post:
      operationId: deleteAllDomainRoleMembers
      summary: Deletes all members from a domain role.
      description: |
        Deletes all members from a specific domain role that is identified by the role name.
      tags:
        - Roles
      parameters:
        - $ref: "#/components/parameters/DomainID"
        - $ref: "./schemas/roles.yaml#/components/parameters/RoleID"
      security:
        - bearerAuth: []
      responses:
        "204":
          description: All role members deleted.
        "400":
          description: Failed due to malformed query parameters.
        "401":
          description: |
            Missing or invalid access token provided.
        "403":
          description: Failed to perform authorization over the entity.
        "404":
          description: A non-existent entity request.
        "422":
          description: Database can't process request.
        "500":
          $ref: "#/components/responses/ServiceError"

  /domains/roles/available-actions:
    get:
      operationId: listAvailableActions
      tags:
        - Roles
      summary: Retrieves available actions.
      description: |
        Retrieves a list of available actions.
      parameters:
        - $ref: "auth.yaml#/components/parameters/DomainID"
      security:
        - bearerAuth: []
      responses:
        "200":
          $ref: "./schemas/roles.yaml#/components/responses/ListAvailableActionsRes"
        "400":
          description: Failed due to malformed query parameters.
        "401":
          description: |
            Missing or invalid access token provided.
        "403":
          description: Failed to perform authorization over the entity.
        "404":
          description: A non-existent entity request.
        "422":
          description: Database can't process request.
        "500":
          $ref: "#/components/responses/ServiceError"

  /domains/{domainID}/invitations:
    post:
      operationId: sendInvitation
      tags:
        - Invitations
      summary: Send invitation
      description: |
        Send invitation to user to join domain.
      parameters:
        - $ref: "#/components/parameters/DomainID"
      requestBody:
        $ref: "#/components/requestBodies/SendInvitationReq"
      security:
        - bearerAuth: []
      responses:
        "201":
          description: Invitation sent.
        "400":
          description: Failed due to malformed JSON.
        "401":
          description: Missing or invalid access token provided.
        "403":
          description: Failed to perform authorization over the entity.
        "404":
          description: A non-existent entity request.
        "409":
          description: Failed due to using an existing identity.
        "415":
          description: Missing or invalid content type.
        "500":
          $ref: "#/components/responses/ServiceError"

    get:
      operationId: listDomainInvitations
      tags:
        - Invitations
      summary: List domain invitations
      description: |
        Retrieves a list of invitations for a given domain. Due to performance concerns, data
        is retrieved in subsets. The API must ensure that the entire
        dataset is consumed either by making subsequent requests, or by
        increasing the subset size of the initial request.
      parameters:
        - $ref: "#/components/parameters/DomainID"
        - $ref: "#/components/parameters/Limit"
        - $ref: "#/components/parameters/Offset"
        - $ref: "#/components/parameters/user_id"
        - $ref: "#/components/parameters/InvitedBy"
        - $ref: "#/components/parameters/State"
      security:
        - bearerAuth: []
      responses:
        "200":
          $ref: "#/components/responses/InvitationPageRes"
        "400":
          description: Failed due to malformed query parameters.
        "401":
          description: |
            Missing or invalid access token provided.
            This endpoint is available only for administrators.
        "403":
          description: Failed to perform authorization over the entity.
        "404":
          description: A non-existent entity request.
        "422":
          description: Database can't process request.
        "500":
          $ref: "#/components/responses/ServiceError"

    delete:
      operationId: deleteInvitation
      summary: Deletes a specific invitation
      description: |
        Deletes a specific invitation that is identified by the user ID and domain ID.
        The user ID is provided in the request body.
      tags:
        - Invitations
      parameters:
        - $ref: "#/components/parameters/DomainID"
      requestBody:
        $ref: "#/components/requestBodies/DeleteInvitationReq"
      security:
        - bearerAuth: []
      responses:
        "204":
          description: Invitation deleted.
        "400":
          description: Failed due to malformed JSON.
        "403":
          description: Failed to perform authorization over the entity.
        "404":
          description: Failed due to non existing user.
        "401":
          description: Missing or invalid access token provided.
        "500":
          $ref: "#/components/responses/ServiceError"

  /invitations:
    get:
      operationId: listUserInvitations
      tags:
        - Invitations
      summary: List user invitations
      description: |
        Retrieves a list of invitations for the current user. Due to performance concerns, data
        is retrieved in subsets. The API must ensure that the entire
        dataset is consumed either by making subsequent requests, or by
        increasing the subset size of the initial request.
      parameters:
        - $ref: "#/components/parameters/domain_id"
        - $ref: "#/components/parameters/Limit"
        - $ref: "#/components/parameters/Offset"
        - $ref: "#/components/parameters/user_id"
        - $ref: "#/components/parameters/InvitedBy"
        - $ref: "#/components/parameters/State"
      security:
        - bearerAuth: []
      responses:
        "200":
          $ref: "#/components/responses/InvitationPageRes"
        "400":
          description: Failed due to malformed query parameters.
        "401":
          description: |
            Missing or invalid access token provided.
            This endpoint is available only for administrators.
        "403":
          description: Failed to perform authorization over the entity.
        "404":
          description: A non-existent entity request.
        "422":
          description: Database can't process request.
        "500":
          $ref: "#/components/responses/ServiceError"

  /invitations/accept:
    post:
      operationId: acceptInvitation
      summary: Accept invitation
      description: |
        Current logged in user accepts invitation to join domain.
      tags:
        - Invitations
      security:
        - bearerAuth: []
      requestBody:
        $ref: "#/components/requestBodies/AcceptInvitationReq"
      responses:
        "204":
          description: Invitation accepted.
        "400":
          description: Failed due to malformed query parameters.
        "401":
          description: Missing or invalid access token provided.
        "404":
          description: A non-existent entity request.
        "422":
          description: Database can't process request.
        "500":
          $ref: "#/components/responses/ServiceError"

  /invitations/reject:
    post:
      operationId: rejectInvitation
      summary: Reject invitation
      description: |
        Current logged in user rejects invitation to join domain.
      tags:
        - Invitations
      security:
        - bearerAuth: []
      requestBody:
        $ref: "#/components/requestBodies/AcceptInvitationReq"
      responses:
        "204":
          description: Invitation rejected.
        "400":
          description: Failed due to malformed query parameters.
        "401":
          description: Missing or invalid access token provided.
        "404":
          description: A non-existent entity request.
        "422":
          description: Database can't process request.
        "500":
          $ref: "#/components/responses/ServiceError"

  /health:
    get:
      summary: Retrieves service health check info.
      tags:
        - Health
      security: []
      responses:
        "200":
          $ref: "#/components/responses/HealthRes"
        "500":
          $ref: "#/components/responses/ServiceError"

components:
  schemas:
    DomainReqObj:
      type: object
      properties:
        name:
          type: string
          example: domainName
          description: Domain name.
        tags:
          type: array
          minItems: 0
          items:
            type: string
          example: ["tag1", "tag2"]
          description: domain tags.
        metadata:
          type: object
          example: { "domain": "example.com" }
          description: Arbitrary, object-encoded domain's data.
        route:
          type: string
          example: domain_route
          description: Domain route.
      required:
        - name
        - route
    Domain:
      type: object
      properties:
        id:
          type: string
          format: uuid
          example: bb7edb32-2eac-4aad-aebe-ed96fe073879
          description: Domain unique identified.
        name:
          type: string
          example: domainName
          description: Domain name.
        tags:
          type: array
          minItems: 0
          items:
            type: string
          example: ["tag1", "tag2"]
          description: domain tags.
        metadata:
          type: object
          example: { "domain": "example.com" }
          description: Arbitrary, object-encoded domain's data.
        route:
          type: string
          example: domain_route
          description: Domain route.
        status:
          type: string
          description: Domain Status
          format: string
          example: enabled
        created_by:
          type: string
          format: uuid
          example: "0d837f56-3f8a-4e2a-9359-6347d0fc9f06 "
          description: User ID of the user who created the domain.
        created_at:
          type: string
          format: date-time
          example: "2019-11-26 13:31:52"
          description: Time when the domain was created.
        updated_by:
          type: string
          format: uuid
          example: "80f66b77-ed74-4e74-9f88-6cce9a0a3049"
          description: User ID of the user who last updated the domain.
        updated_at:
          type: string
          format: date-time
          example: "2019-11-26 13:31:52"
          description: Time when the domain was last updated.
      xml:
        name: domain

    DomainsPage:
      type: object
      properties:
        domains:
          type: array
          minItems: 0
          uniqueItems: true
          items:
            $ref: "#/components/schemas/Domain"
        total:
          type: integer
          example: 1
          description: Total number of items.
        offset:
          type: integer
          description: Number of items to skip during retrieval.
        limit:
          type: integer
          example: 10
          description: Maximum number of items to return in one page.
      required:
        - total
    DomainUpdate:
      type: object
      properties:
        name:
          type: string
          example: domainName
          description: Domain name.
        tags:
          type: array
          minItems: 0
          items:
            type: string
          example: ["tag1", "tag2"]
          description: domain tags.
        metadata:
          type: object
          example: { "domain": "example.com" }
          description: Arbitrary, object-encoded domain's data.

    SendInvitationReqObj:
      type: object
      properties:
        invitee_user_id:
          type: string
          format: uuid
          example: bb7edb32-2eac-4aad-aebe-ed96fe073879
          description: User unique identifier.
        role_id:
          type: string
          format: uuid
          example: bb7edb32-2eac-4aad-aebe-ed96fe073879
          description: Identifier for the role to be assigned to the user.
      required:
        - invitee_user_id
        - role_id

    Invitation:
      type: object
      properties:
        invited_by:
          type: string
          format: uuid
          example: bb7edb32-2eac-4aad-aebe-ed96fe073879
          description: User unique identifier.
        invitee_user_id:
          type: string
          format: uuid
          example: bb7edb32-2eac-4aad-aebe-ed96fe073879
          description: Invitee user unique identifier.
        domain_id:
          type: string
          format: uuid
          example: bb7edb32-2eac-4aad-aebe-ed96fe073879
          description: Domain unique identifier.
        role_id:
          type: string
          format: uuid
          example: bb7edb32-2eac-4aad-aebe-ed96fe073879
          description: Role unique identifier.
        role_name:
          type: string
          example: editor
          description: Role name.
        actions:
          type: array
          items:
            type: string
          example: ["read", "write"]
          description: Actions allowed for the role.
        created_at:
          type: string
          format: date-time
          example: "2019-11-26 13:31:52"
          description: Time when the group was created.
        updated_at:
          type: string
          format: date-time
          example: "2019-11-26 13:31:52"
          description: Time when the group was created.
        confirmed_at:
          type: string
          format: date-time
          example: "2019-11-26 13:31:52"
          description: Time when the group was created.
      xml:
        name: invitation

    InvitationPage:
      type: object
      properties:
        invitations:
          type: array
          minItems: 0
          uniqueItems: true
          items:
            $ref: "#/components/schemas/Invitation"
        total:
          type: integer
          example: 1
          description: Total number of items.
        offset:
          type: integer
          description: Number of items to skip during retrieval.
        limit:
          type: integer
          example: 10
          description: Maximum number of items to return in one page.
      required:
        - invitations
        - total
        - offset

    Error:
      type: object
      properties:
        error:
          type: string
          description: Error message
      example: { "error": "malformed entity specification" }

  parameters:
    DomainID:
      name: domainID
      description: Unique domain identified.
      in: path
      schema:
        type: string
        format: uuid
      required: true
      example: bb7edb32-2eac-4aad-aebe-ed96fe073879
    Status:
      name: status
      description: Domain status.
      in: query
      schema:
        type: string
        default: enabled
      required: false
      example: enabled
    DomainName:
      name: name
      description: Domain's name.
      in: query
      schema:
        type: string
      required: false
      example: "domainName"
    Permission:
      name: permission
      description: permission.
      in: query
      schema:
        type: string
      required: false
      example: "edit"
    ApiKeyId:
      name: keyID
      description: API Key ID.
      in: path
      schema:
        type: string
        format: uuid
      required: true
    Limit:
      name: limit
      description: Size of the subset to retrieve.
      in: query
      schema:
        type: integer
        default: 10
        maximum: 100
        minimum: 1
      required: false
    Offset:
      name: offset
      description: Number of items to skip during retrieval.
      in: query
      schema:
        type: integer
        default: 0
        minimum: 0
      required: false
    Metadata:
      name: metadata
      description: Metadata filter. Filtering is performed matching the parameter with metadata on top level. Parameter is json.
      in: query
      required: false
      schema:
        type: object
        additionalProperties: {}
    Type:
      name: type
      description: The type of the API Key.
      in: query
      schema:
        type: integer
        default: 0
        minimum: 0
      required: false
    Subject:
      name: subject
      description: The subject of an API Key
      in: query
      schema:
        type: string
      required: false
    UserID:
      name: userID
      description: Unique user identifier.
      in: path
      schema:
        type: string
        format: uuid
      required: true
      example: bb7edb32-2eac-4aad-aebe-ed96fe073879
    user_id:
      name: user_id
      description: Unique user identifier.
      in: query
      schema:
        type: string
        format: uuid
      example: bb7edb32-2eac-4aad-aebe-ed96fe073879
    domain_id:
      name: domain_id
      description: Unique identifier for a domain.
      in: query
      schema:
        type: string
        format: uuid
      example: bb7edb32-2eac-4aad-aebe-ed96fe073879
    InvitedBy:
      name: invited_by
      description: Unique identifier for a user that invited the user.
      in: query
      schema:
        type: string
        format: uuid
      required: false
      example: bb7edb32-2eac-4aad-aebe-ed96fe073879
    State:
      name: state
      description: Invitation state.
      in: query
      schema:
        type: string
        enum:
          - pending
          - accepted
          - all
      required: false
      example: accepted
    RoleID:
      name: roleID
      description: Unique role identifier.
      in: query
      schema:
        type: string
        format: uuid
      required: true
      example: bb7edb32-2eac-4aad-aebe-ed96fe073879

  requestBodies:
    DomainCreateReq:
      description: JSON-formatted document describing the new domain to be registered
      required: true
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/DomainReqObj"
    DomainUpdateReq:
      description: JSON-formated document describing the name, tags, and metadata of the domain to be updated
      required: true
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/DomainUpdate"
    SendInvitationReq:
      description: JSON-formatted document describing request for sending invitation
      required: true
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/SendInvitationReqObj"
    AcceptInvitationReq:
      description: JSON-formatted document describing request for accepting invitation
      required: true
      content:
        application/json:
          schema:
            type: object
            properties:
              domain_id:
                type: string
                format: uuid
                example: bb7edb32-2eac-4aad-aebe-ed96fe073879
                description: Domain unique identifier.
            required:
              - domain_id
    DeleteInvitationReq:
      description: JSON-formatted document describing request for deleting invitation
      required: true
      content:
        application/json:
          schema:
            type: object
            properties:
              user_id:
                type: string
                format: uuid
                example: bb7edb32-2eac-4aad-aebe-ed96fe073879
                description: User unique identifier.
            required:
              - user_id

  responses:
    ServiceError:
      description: Unexpected server-side error occurred.

    DomainCreateRes:
      description: Create new domain.
      headers:
        Location:
          schema:
            type: string
            format: url
          description: Registered domain relative URL in the format `/domains/<domainID_id>`
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/Domain"

    DomainRes:
      description: Data retrieved.
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/Domain"
    DomainsPageRes:
      description: Data retrieved.
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/DomainsPage"
    InvitationRes:
      description: Data retrieved.
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/Invitation"
      links:
        delete:
          operationId: deleteInvitation
          parameters:
            userID: $response.body#/user_id
            domainID: $response.body#/domain_id

    InvitationPageRes:
      description: Data retrieved.
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/InvitationPage"
    HealthRes:
      description: Service Health Check.
      content:
        application/health+json:
          schema:
            $ref: "./schemas/health_info.yaml"

  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: |
        * Users access: "Authorization: Bearer <user_token>"

security:
  - bearerAuth: []
