openapi: 3.0.0
info:
  version: '0.0'
  title: Qomon
  description: |-
    This is Qomon's API definition.

    To get an authorization go to [Qomon's setting page](https://qomon.app/settings/extensions/connect) and create an API key.
servers:
  - description: Qomon production
    url: https://qomon.app/api
  - description: Qomon integration
    url: https://test.quorumapps.com/api
  - description: Qomon local
    url: http://localhost:8080


tags:
  - name: Contact mandates
    description: Mandates operations
  - name: Mandate settings
    description: Mandates settings operations

paths:
  /contacts/{contactId}/mandates:
    get:
      summary: Get mandates of a contact
      tags:
        - Contact mandates
      description: Get all mandates of a contact
      parameters:
        - $ref: '#/components/parameters/contactId'
      responses:
        '200':
          description: A list of mandates
          content:
            application/json:
              schema:
                type: object
                properties:
                  status: 
                    type: string
                    example: success
                  data:
                    type: object
                    properties:
                      mandates:
                        type: array
                        items:
                          $ref: '#/components/schemas/ContactMandate'
              examples:
                Response mandates list:
                  $ref: '#/components/examples/ResponseMandates'
        '404':
          description: Contact not found
    post:
      summary: Create one or several mandates for a contact
      tags:
        - Contact mandates
      parameters:
        - $ref: '#/components/parameters/contactId'
      requestBody:
        required: true
        content:
          application/json:
            schema:
                properties:
                  data:
                    type: object
                    properties:
                      mandates:
                        type: array
                        items:
                          $ref: '#/components/schemas/ContactMandate'
                      mandate:
                        $ref: '#/components/schemas/ContactMandate'
                        description: Only if request body contains a single mandate (deprecated)
            examples:
              Request mandates list:
                $ref: '#/components/examples/RequestMandates'
              Request single mandate (deprecated):
                $ref: '#/components/examples/RequestMandate'
      responses:
        '201':
          description: Mandate created
          content:
            application/json:
              schema:
                type: object
                properties:
                  status: 
                    type: string
                    example: success
                  data:
                    type: object
                    properties:
                      mandates:
                        type: array
                        items:
                          $ref: '#/components/schemas/ContactMandate'
              examples:
                Response mandates list:
                  $ref: '#/components/examples/ResponseMandates'
                Response single mandate (deprecated):
                  $ref: '#/components/examples/ResponsMandate'
        '207': 
          description: Only a few mandates created
          content:
            application/json:
              schema:
                type: object
                properties:
                  status: 
                    type: string
                    example: success
                  data:
                    type: object
                    properties:
                      mandates:
                        type: array
                        items:
                          $ref: '#/components/schemas/ContactMandate'
                      errors:
                        $ref: '#/components/schemas/Errors'
              examples:
                Response multi status:
                  $ref: '#/components/examples/ResponseMultiStatus'
        '400':
          description: Invalid input
        '404':
          description: Contact not found
        '500':
          description: Internal server error, no mandates created
    patch:
      summary: Update a mandate for a contact
      tags:
        - Contact mandates
      description: Update a mandate for a contact
      parameters:
        - $ref: '#/components/parameters/contactId'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              properties:
                data:
                  type: object
                  properties:
                    mandates:
                      type: array
                      items:
                        $ref: '#/components/schemas/ContactMandate'
                    mandate:
                      $ref: '#/components/schemas/ContactMandate'
                      description: Deprecated, use mandates instead
            examples:
              Request mandates list:
                $ref: '#/components/examples/RequestMandates'
              Request single mandate (deprecated):
                $ref: '#/components/examples/RequestMandate'
      responses:
        '200':
          description: Mandate updated
          content:
            application/json:
              schema:
                type: object
                properties:
                  status: 
                    type: string
                    example: success
                  data:
                    type: object
                    properties:
                      mandates:
                        $ref: '#/components/schemas/ContactMandate'
                      mandate:
                        $ref: '#/components/schemas/ContactMandate'
                        description: Only if request body contains a single mandate (deprecated)
              examples:
                Response mandates list:
                  $ref: '#/components/examples/ResponseMandates'
                Response single mandate (deprecated):
                  $ref: '#/components/examples/ResponsMandate'
        '207': 
          description: Only a few mandates updated
          content:
            application/json:
              schema:
                type: object
                properties:
                  status: 
                    type: string
                    example: success
                  data:
                    type: object
                    properties:
                      mandates:
                        type: array
                        items:
                          $ref: '#/components/schemas/ContactMandate'
                      errors:
                        $ref: '#/components/schemas/Errors'
              examples:
                Response multi status:
                  $ref: '#/components/examples/ResponseMultiStatus'
                    
        '400':
          description: Invalid input
        '404':
          description: Contact not found
    delete:
      summary: Delete a mandate for a contact
      tags:
        - Contact mandates
      description: Delete a mandate for a contact
      parameters:
        - $ref: '#/components/parameters/contactId'
      requestBody:
        required: true
        content:
          application/json:
            schema:
                properties:
                  data:
                    type: object
                    properties:
                      mandates:
                        $ref: '#/components/schemas/ContactMandate'
                      mandate:
                        $ref: '#/components/schemas/ContactMandate'
                        description: Deprecated, use mandates instead
            examples:
              Request mandates list:
                value:
                  data:
                    mandates:
                      - id: 23
                      - id: 26
                      - id: 27
              Request single mandate (deprecated):
                value:
                  data:
                    mandate:
                      id: 23
      responses:
        '204':
          description: Mandate deleted
        '207': 
          description: Only a few mandates deleted
          content:
            application/json:
              schema:
                type: object
                properties:
                  status: 
                    type: string
                    example: success
                  data:
                    type: object
                    properties:
                      mandates:
                        type: array
                        items:
                          $ref: '#/components/schemas/ContactMandate'
                      errors:
                        $ref: '#/components/schemas/Errors'
              examples:
                Response multi status:
                  value:
                    status: success
                    data:
                      msg: Only a few mandates deleted
                      errors:
                        - index: 1
                          msg: mandate not found
                          status: 404
        '400':
          description: Invalid input
        '404':
          description: Contact not found

  /contacts/{contactId}/all_mandates:
    delete:
      summary: Delete all mandates for a contact
      tags:
        - Contact mandates
      description: Delete all mandates for a contact
      parameters:
        - $ref: '#/components/parameters/contactId'
      responses:
        '204':
          description: Mandates deleted
        '400':
          description: Invalid input
        '404':
          description: Mandate not found

  /mandates/settings:
    get:
      summary: Get mandates settings
      tags:
        - Mandate settings
      description: Get all mandates settings
      responses:
        '200':
          description: A list of mandates settings
          content:
            application/json:
              schema:
                type: object
                properties:
                  status: 
                    type: string
                    example: success
                  data:
                    type: object
                    properties:
                      settings:
                        $ref: '#/components/schemas/Settings'
        '404':
          description: Settings not found

  /mandates/organisations:
    get:
      summary: Search organisations that contain a string
      tags:
        - Mandate settings
      description: Used for autocomplete
      parameters:
        - $ref: '#/components/parameters/search'
      responses:
        '200':
          description: A list of organisations
          content:
            application/json:
              schema:
                type: object
                properties:
                  status: 
                    type: string
                    example: success
                  data:
                    type: object
                    properties:
                      organisations:
                        type: array
                        items:
                          $ref: '#/components/schemas/Organisation'

  /mandates/organisation:
    post:
      summary: Create an organisation
      tags:
        - Mandate settings
      description: Create an organisation
      requestBody:
        required: true
        content:
          application/json:
            schema:
                properties:
                  data:
                    type: object
                    properties:
                      organisation:
                        $ref: '#/components/schemas/Organisation'
      responses:
        '201':
          description: Organisation created
          content:
            application/json:
              schema:
                type: object
                properties:
                  status: 
                    type: string
                    example: success
                  data:
                    type: object
                    properties:
                      organisation:
                        $ref: '#/components/schemas/Organisation'
        '400':
          description: Invalid input
        '403':
          description: Organisation already exists
        '404':
          description: Organisation not found
    patch:
      summary: Update an organisation
      tags:
        - Mandate settings
      description: Update an organisation
      requestBody:
        required: true
        content:
          application/json:
            schema:
                properties:
                  data:
                    type: object
                    properties:
                      organisation:
                        $ref: '#/components/schemas/Organisation'
      responses:
        '200':
          description: Organisation updated
          content:
            application/json:
              schema:
                type: object
                properties:
                  status: 
                    type: string
                    example: success
                  data:
                    type: object
                    properties:
                      organisation:
                        $ref: '#/components/schemas/Organisation'
        '400':
          description: Invalid input
        '403':
          description: Organisation already exists
        '404':
          description: Organisation not found
    delete:
      summary: Delete an organisation
      tags:
        - Mandate settings
      description: Delete an organisation
      requestBody:
        required: true
        content:
          application/json:
            schema:
                properties:
                  data:
                    type: object
                    properties:
                      organisation:
                        $ref: '#/components/schemas/Organisation'
      responses:
        '204':
          description: Organisation deleted
        '400':
          description: Invalid input
        '404':
          description: Organisation not found
  
  /mandates/titles:
    get:
      summary: Search titles that contain a string
      tags:
        - Mandate settings
      description: Used for autocomplete
      parameters:
        - $ref: '#/components/parameters/search'
        - $ref: '#/components/parameters/contact_gender'
      responses:
        '200':
          description: A list of titles
          content:
            application/json:
              schema:
                type: object
                properties:
                  status: 
                    type: string
                    example: success
                  data:
                    type: object
                    properties:
                      titles:
                        type: array
                        items:
                          type: string
                          example: "Mayor"
                      titles_whole_obj:
                        type: array
                        items:
                          $ref: '#/components/schemas/Title'
              examples:
                Response when contact_gender provided:
                  value:
                    status: success
                    data:
                      titles:
                        - "Mayor"
                        - "Treasurer"
                Response when contact_gender not provided:
                  value:
                    data:
                      titles_whole_obj:
                        - id: 1
                          neutral: "Mayor"
                          feminine: "Mayoress"
                          masculine: "Mayor"
                          normalized_name: "mayor"
                        - id: 2
                          neutral: "Treasurer"
                          feminine: "Treasurer"
                          masculine: "Treasurer"
                          normalized_name: "treasurer"
  /mandates/title:
    get:
      summary: Get full title object by value
      tags:
        - Mandate settings
      description: Allow to retrieve gender translations of a title
      parameters:
        - $ref: '#/components/parameters/search'
        - $ref: '#/components/parameters/contact_gender'
      responses:
        '200':
          description: A title object
          content:
            application/json:
              schema:
                type: object
                properties:
                  status: 
                    type: string
                    example: success
                  data:
                    type: object
                    properties:
                      title:
                        $ref: '#/components/schemas/Title'
        '404':
          description: Title not found

    post:
      summary: Create a title
      tags:
        - Mandate settings
      description: Create a title
      requestBody:
        required: true
        content:
          application/json:
            schema:
                properties:
                  data:
                    type: object
                    properties:
                      title:
                        $ref: '#/components/schemas/Title'
      responses:
        '201':
          description: Title created
          content:
            application/json:
              schema:
                type: object
                properties:
                  status: 
                    type: string
                    example: success
                  data:
                    type: object
                    properties:
                      title:
                        $ref: '#/components/schemas/Title'
        '400':
          description: Invalid input
        '403':
          description: Title already exists
        '404':
          description: Title not found
    patch:
      summary: Update a title
      tags:
        - Mandate settings
      description: Update a title
      requestBody:
        required: true
        content:
          application/json:
            schema:
                properties:
                  data:
                    type: object
                    properties:
                      title:
                        $ref: '#/components/schemas/Title'
      responses:
        '200':
          description: Title updated
          content:
            application/json:
              schema:
                type: object
                properties:
                  status: 
                    type: string
                    example: success
                  data:
                    type: object
                    properties:
                      title:
                        $ref: '#/components/schemas/Title'
        '400':
          description: Invalid input
        '403':
          description: Title already exists
        '404':
          description: Title not found
    delete:
      summary: Delete a title
      tags:
        - Mandate settings
      description: Delete a title
      requestBody:
        required: true
        content:
          application/json:
            schema:
                properties:
                  data:
                    type: object
                    properties:
                      title:
                        $ref: '#/components/schemas/Title'
      responses:
        '204':
          description: Title deleted
        '400':
          description: Invalid input
        '404':
          description: Title not found
    

components:
  parameters:
    contactId:
      name: contactId
      in: path
      description: ID of a contact
      required: true
      schema:
        type: integer
        example: 83854766
    search:
      name: search
      in: query
      description: Search for a contact
      required: false
      schema:
        type: string
        example: mayor
    contact_gender:
      name: contact_gender
      in: query
      description: gender of a contact to set correct title, if not provided whole tiltes objects are returned
      required: false
      schema:
        type: string
        enum: [M, F, O]
    value:
      name: value
      in: query
      description: Value of a title
      required: true
      schema:
        type: string
    gender:
      name: gender
      in: query
      description: A gender character
      required: true
      schema:
        type: string
        enum: [M, F, O]

  examples:
    ResponseMandates:
      value:
        status: success
        data:
          mandates:
            - id: 1
              group_id: 1
              contact_id: 1
              title: "Mayor"
              organisation: "City Hall"
              subentity: "Public Relations"
              start_date: "2019-10-13T15:50:24.163Z"
              end_date: "2022-10-13T15:50:24.163Z"
              mail: "example@example.com"
              phone: "0612345987"
              address:
                street: "Rue de la Loi"
                number: "16"
                postal_code: "1000"
                city: "Brussels"
                country: "Belgium"
            - id: 2
              group_id: 1
              contact_id: 1
              title: "Treasurer"
              organisation: "City Hall"
              subentity: "Public Relations"
              start_date: "2017-10-13T15:50:24.163Z"
              end_date: "20119-10-13T15:50:24.163Z"
              mail: "example@example.com"
              phone: "0612345987"
              address:
                street: "Rue de la Loi"
                number: "16"
                postal_code: "1000"
                city: "Brussels"
                country: "Belgium"
    ResponsMandate:
      value:
        status: success
        data:
          mandate:
            id: 1
            group_id: 1
            contact_id: 1
            title: "Mayor"
            organisation: "City Hall"
            subentity: "Public Relations"
            start_date: "2019-10-13T15:50:24.163Z"
            end_date: "2022-10-13T15:50:24.163Z"
            address:
              street: "Rue de la Loi"
              number: "16"
              postal_code: "1000"
              city: "Brussels"
              country: "Belgium"
    ResponseMultiStatus:
      value:
        status: success
        data:
          msg: Only a few mandates edited
          mandates:
            - id: 1
              group_id: 1
              contact_id: 1
              title: "Mayor"
              organisation: "City Hall"
              subentity: "Public Relations"
              start_date: "2019-10-13T15:50:24.163Z"
              end_date: "2022-10-13T15:50:24.163Z"
              mail: "example@example.com"
              phone: "0612345987"
              address:
                street: "Rue de la Loi"
                number: "16"
                postal_code: "1000"
                city: "Brussels"
                country: "Belgium"
          errors:
            - index: 1
              msg: invalid title
              status: 400

    RequestMandates:
      value:
        data: 
          mandates:
            - title: "Mayor"
              organisation: "City Hall"
              subentity: "Public Relations"
              start_date: "2019-10-13T15:50:24.163Z"
              end_date: "2022-10-13T15:50:24.163Z"
              mail: "example@example.com"
              phone: "0612345987"
              address:
                street: "Rue de la Loi"
                number: "16"
                postal_code: "1000"
                city: "Brussels"
                country: "Belgium"
            - title: "Treasurer"
              organisation: "City Hall"
              subentity: "Public Relations"
              start_date: "2017-10-13T15:50:24.163Z"
              end_date: "20119-10-13T15:50:24.163Z"
              mail: "example@example.com"
              phone: "0612345987"
              address:
                street: "Rue de la Loi"
                number: "16"
                postal_code: "1000"
                city: "Brussels"
                country: "Belgium"
    RequestMandate:
      value:
        data:
          mandate:
            title: "Mayor"
            organisation: "City Hall"
            subentity: "Public Relations"
            start_date: "2019-10-13T15:50:24.163Z"
            end_date: "2022-10-13T15:50:24.163Z"
            mail: "example@example.com"
            phone: "0612345987"
            address:
              street: "Rue de la Loi"
              number: "16"
              postal_code: "1000"
              city: "Brussels"
              country: "Belgium"
      

  schemas:
    ContactMandate:
      type: object
      properties:
        id:
          type: integer
        group_id:
          type: integer
        contact_id:
          type: integer
        title:
          type: string
        organisation:
          type: string
        subentity:
          type: string
        start_date:
          type: string
          format: date-time
          example: "2022-10-13T15:50:24.163Z"
        end_date:
          type: string
          format: date-time
          example: "2022-10-13T15:50:24.163Z"
        mail:
          type: string
        phone:
          type: string
        address:
          type: object
        
    Mandate:
      type: object
      properties:
        id:
          type: integer
        group_id:
          type: integer
        contact_id:
          type: integer
        title:
          $ref: '#/components/schemas/Title'
        organisation:
          $ref: '#/components/schemas/Organisation'
        subentity:
          $ref: '#/components/schemas/Organisation'
        start_date:
          type: string
          format: date-time
          example: "2022-10-13T15:50:24.163Z"
        end_date:
          type: string
          format: date-time
          example: "2022-10-13T15:50:24.163Z"
        mail:
          type: string
        phone:
          type: string
        address:
          type: object

    Title:
      type: object
      properties:
        id:
          type: integer
        neutral:
          type: string
        feminine:
          type: string
        masculine:
          type: string

    Organisation:
      type: object
      properties:
        id:
          type: integer
        name:
          type: string
        type: 
          type: object
          properties:
            id:
              type: integer
            name:
              type: string

    Settings:
      type: object
      properties:
        id:
          type: integer
        titles:
          type: array
          items:
            $ref: '#/components/schemas/Title'
        organisations:
          type: array
          items:
            $ref: '#/components/schemas/Organisation'
        group_id:
          type: array
          items:
            type: integer

    Errors:
      type: array
      items:
        type: object
        properties:
          index:
            type: integer
            description: Index of the mandate in the request
          msg:
            type: string
            example: invalid title
          status:
            type: integer
            example: 400