openapi: 3.0.2
info:
  version: ''
  title: 'DC Project'
  description: 'A free community program for create constitution'

paths:
  /articles:
    get:
      summary: Get all articles
      tags:
        - article
      operationId: getArticles
      parameters:
        - $ref: '#/components/parameters/page'
        - $ref: '#/components/parameters/limit'
        - $ref: '#/components/parameters/articleSort'
        - $ref: '#/components/parameters/direction'
        - $ref: '#/components/parameters/search'
        - $ref: '#/components/parameters/createdBy'
        - name: workgroup
          in: query
          description: ID of workgroup
          example: 82a0e60a-bb55-dbc0-1c3d-0a804df2b5df
          required: false
          schema:
            type: string
            format: uuid
      responses:
        200:
          description: The Article objects
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Paginated'
                  - type: object
                    properties:
                      result:
                        type: array
                        maxItems: 50
                        items:
                          $ref: '#/components/schemas/ArticleListingResponse'
        400:
          description: BadReqest
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/400'
    post:
      security:
        - JWTAuth: []
      summary: Create new Article
      tags:
        - article
      operationId: insertArticle
      requestBody:
        required: true
        content:
          application/json:
            schema:
              required:
                - title
                - content
                - description
                - tags
              properties:
                title:
                  type: string
                  example:
                    Limit power of press
                content:
                  type: string
                  minLength: 50
                  maxLength: 6000
                  example:
                    Lorem upsum...
                description:
                  type: string
                  minLength: 50
                  maxLength: 6000
                  example:
                    I think is the bether choice
                tags:
                  type: array
                  items:
                    type: string
                    maxItems: 15
                  default: [ ]
                  example: [ power, press ]
                anonymous:
                  type: boolean
                  default: true
                draft:
                  type: boolean
                  default: false
                workgroup:
                  default: null
                  additionalProperties: false
                  required:
                    - id
                  properties:
                    id:
                      $ref: "#/components/schemas/UUID"
      responses:
        200:
          description: Article created
          content:
            application/json:
              schema:
                properties:
                  id:
                    type: string
                    format: uuid
                  versionId:
                    type: string
                    format: uuid
                  versionNumber:
                    type: integer
        400:
          description: BadReqest
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/400'
        401:
          $ref: '#/components/responses/401'
        403:
          description: Forbiden
          content:
            application/json:
              schema:
                description: Forbiden
                properties:
                  statusCode:
                    type: integer
                  title:
                    type: string

  /articles/{article}:
    parameters:
      - $ref: '#/components/parameters/article'
    get:
      summary: Get one article
      tags:
        - article
      operationId: getArticle
      parameters:
        - $ref: '#/components/parameters/page'
        - $ref: '#/components/parameters/limit'
        - $ref: '#/components/parameters/sort'
        - $ref: '#/components/parameters/direction'
        - $ref: '#/components/parameters/search'
      responses:
        200:
          description: The Article objects
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ArticleResponse'
        400:
          description: BadReqest
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/400'
        404:
          description: BadReqest
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/404'

  /articles/{article}/versions:
    parameters:
      - $ref: '#/components/parameters/article'
    get:
      summary: Get all versions of articles
      tags:
        - article
      operationId: getArticleVersions
      parameters:
        - $ref: '#/components/parameters/page'
        - $ref: '#/components/parameters/limit'
        - $ref: '#/components/parameters/sort'
        - $ref: '#/components/parameters/direction'
        - $ref: '#/components/parameters/search'
      responses:
        200:
          description: The versions of Article
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Paginated'
                  - type: object
                    properties:
                      result:
                        type: array
                        items:
                          additionalProperties: false
                          properties:
                            id:
                              type: string
                              format: uuid
                            title:
                              type: string
                            draft:
                              type: boolean
                            lastVersion:
                              type: boolean
                            createdBy:
                              type: object
                              additionalProperties: false
                              properties:
                                id:
                                  type: string
                                  format: uuid
                                name:
                                  type: object
                                  properties:
                                    firstName:
                                      type: string
                                    lastName:
                                      type: string
                                email:
                                  type: string
                            workgroup:
                              type: object
                              nullable: true
                              additionalProperties: false
                              properties:
                                id:
                                  type: string
                                  format: uuid
                                name:
                                  type: string
        400:
          description: BadReqest
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/400'

  /login:
    post:
      summary: sign in
      tags:
        - authentification
      operationId: login
      requestBody:
        description: Login
        required: true
        content:
          application/json:
            schema:
              required:
                - username
                - password
              properties:
                username:
                  type: string
                  description: username
                  example:
                    john-doe
                password:
                  type: string
                  description: Pasword
                  example:
                    azerty
      responses:
        200:
          description: return JWT
          content:
            text/plain:
              schema:
                type: string
                format: byte
                example:
                  'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJBdXRoZW50aWNhdGlvbiIsImlzcyI6ImRjLXByb2plY3QuZnIiLCJpZCI6ImQ1NDRhNmE4LWJhYjgtNDU2MC05NWIxLThhZjAyMDNkOTEwNCIsImV4cCI6MTU2NzA3Mzc0Mn0.0VTetv8fZFjVgpJ-bwJpidGNHJUOmgj8vuZcZXzwnLa7TtFwcXWvh3bDPYHqB66nmOfXyM57XnHDbmRwtipCag'
            application/json:
              schema:
                properties:
                  token:
                    type: string
                    example:
                      'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJBdXRoZW50aWNhdGlvbiIsImlzcyI6ImRjLXByb2plY3QuZnIiLCJpZCI6ImQ1NDRhNmE4LWJhYjgtNDU2MC05NWIxLThhZjAyMDNkOTEwNCIsImV4cCI6MTU2NzA3Mzc0Mn0.0VTetv8fZFjVgpJ-bwJpidGNHJUOmgj8vuZcZXzwnLa7TtFwcXWvh3bDPYHqB66nmOfXyM57XnHDbmRwtipCag'
  /register:
    post:
      summary: Create account
      tags:
        - authentification
      operationId: register
      requestBody:
        content:
          application/json:
            schema:
              type: object
              required:
                - name
                - birthday
                - email
                - user
              properties:
                name:
                  type: object
                  required:
                    - firstName
                    - lastName
                  properties:
                    firstName:
                      type: string
                      example:
                        john
                    lastName:
                      type: string
                      example:
                        Doe
                birthday:
                  type: string
                  format: 'date'
                  example: '1984-12-25'
                email:
                  type: string
                  format: email
                  example: my.email@dc-project.fr
                user:
                  type: object
                  required:
                    - username
                    - password
                  properties:
                    username:
                      type: string
                      example:
                        john-doe
                    password:
                      type: string
                      example:
                        azerty
                      format: password
      responses:
        200:
          description: User created and JWT returned
          content:
            text/plain:
              example:
                'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJBdXRoZW50aWNhdGlvbiIsImlzcyI6ImRjLXByb2plY3QuZnIiLCJpZCI6ImQ1NDRhNmE4LWJhYjgtNDU2MC05NWIxLThhZjAyMDNkOTEwNCIsImV4cCI6MTU2NzA3Mzc0Mn0.0VTetv8fZFjVgpJ-bwJpidGNHJUOmgj8vuZcZXzwnLa7TtFwcXWvh3bDPYHqB66nmOfXyM57XnHDbmRwtipCag'
            application/json:
              schema:
                properties:
                  token:
                    type: string
                    example:
                      'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJBdXRoZW50aWNhdGlvbiIsImlzcyI6ImRjLXByb2plY3QuZnIiLCJpZCI6ImQ1NDRhNmE4LWJhYjgtNDU2MC05NWIxLThhZjAyMDNkOTEwNCIsImV4cCI6MTU2NzA3Mzc0Mn0.0VTetv8fZFjVgpJ-bwJpidGNHJUOmgj8vuZcZXzwnLa7TtFwcXWvh3bDPYHqB66nmOfXyM57XnHDbmRwtipCag'
        400:
          description: Bad request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/400'
  /auth/passwordless:
    post:
      summary: Send a connexion link by email
      description: Send a connexion link by email with the token required to the connexion
      externalDocs:
        description: Explanation of Passwordless auth
        url: https://en.wikipedia.org/wiki/Passwordless_authentication
      tags:
        - authentification
      operationId: passwordless
      requestBody:
        content:
          application/json:
            schema:
              properties:
                email:
                  type: string
                  format: email
                  description: email to send the token
                  example:
                    my.email@dc-project.fr
                url:
                  type: string
                  description: url tu redirect with the token
                  example:
                    http://dc-project.fr/auth/passwordless
      responses:
        204:
          description: email send
        404:
          description: no user with this email

  /citizens:
    get:
      security:
        - JWTAuth: []
      summary: Get all citizens
      tags:
        - citizen
      operationId: getCitizens
      parameters:
        - $ref: '#/components/parameters/page'
        - $ref: '#/components/parameters/limit'
        - $ref: '#/components/parameters/citizenSort'
        - $ref: '#/components/parameters/direction'
        - $ref: '#/components/parameters/search'
      responses:
        200:
          description: The Citizen objects
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Paginated'
                  - type: object
                    properties:
                      result:
                        type: array
                        items:
                          $ref: '#/components/schemas/CitizenListResponse'
        400:
          description: BadReqest
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/400'
        401:
          $ref: '#/components/responses/401'
  /citizens/current:
    get:
      security:
        - JWTAuth: []
      summary: Get Citizen
      tags:
        - citizen
      operationId: getCurrentCitizen
      responses:
        200:
          description: The Citizen object
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CitizenResponse'
  /citizens/{citizen}:
    parameters:
      - $ref: '#/components/parameters/citizen'
    get:
      security:
        - JWTAuth: []
      summary: Get Citizen
      tags:
        - citizen
      operationId: getCitizen
      responses:
        200:
          description: The Citizen object
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CitizenResponse'
        404:
          description: Citizen not found
        401:
          $ref: '#/components/responses/401'
  /citizens/{citizen}/password/change:
    parameters:
      - $ref: '#/components/parameters/citizen'
    put:
      security:
        - JWTAuth: [ ]
      summary: Change Citizen Password
      tags:
        - citizen
      operationId: changePassword
      requestBody:
        required: true
        content:
          application/json:
            schema:
              required:
                - oldPassword
                - newPassword
              properties:
                oldPassword:
                  type: string
                  format: password
                  example:
                    azerty
                newPassword:
                  type: string
                  format: password
                  example:
                    qwerty
      responses:
        201:
          description: Password changed
        400:
          description: Bad request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/400'
        401:
          $ref: '#/components/responses/401'
        404:
          description: Citizen not found

  /articles/{article}/comments:
    parameters:
      - $ref: '#/components/parameters/article'
    get:
      summary: Get comments of one article
      tags:
        - comment
        - article
      parameters:
        - $ref: '#/components/parameters/page'
        - $ref: '#/components/parameters/limit'
        - $ref: '#/components/parameters/search'
        - name: sort
          in: query
          required: false
          example:
            - createdAt
            - votes
          schema:
            type: string
            default: createdAt
            enum:
              - createdAt
              - votes
      responses:
        200:
          description: Return paginated comments of article
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Paginated'
                  - type: object
                    properties:
                      result:
                        type: array
                        items:
                          $ref: '#/components/schemas/CommentResponse'
        400:
          description: BadReqest
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/400'
    post:
      security:
        - JWTAuth: [ ]
      summary: Create Comment to article
      tags:
        - comment
        - article
      requestBody:
        content:
          application/json:
            schema:
              type: object
              required:
                - content
              properties:
                content:
                  type: string
                  minLength: 20
                  maxLength: 6000
                  example:
                    Lorem ipsum dolor sit amet, consectetur adipiscing elit.Lorem ipsum...
      responses:
        201:
          description: Return created Comment
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CommentResponse'
        400:
          description: BadReqest
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/400'
        401:
          $ref: '#/components/responses/401'
  /comments/{comment}:
    parameters:
      - $ref: '#/components/parameters/comment'
    get:
      summary: Get Comment by Comment ID
      tags:
        - comment
      responses:
        200:
          description: Return Comment
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CommentResponse'
    post:
      security:
        - JWTAuth: []
      summary: create comment
      tags:
        - comment
      requestBody:
        content:
          application/json:
            schema:
              required:
                - content
              properties:
                content:
                  type: string
                  minLength: 20
                  maxLength: 6000
                  example:
                    Lorem ipsum dolor sit amet, consectetur adipiscing elit.
      responses:
        201:
          description: Return updated comment
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CommentResponse'
        400:
          description: BadReqest
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/400'
        401:
          $ref: '#/components/responses/401'
        404:
          description: No comment found
    put:
      security:
        - JWTAuth: []
      summary: Edit existing comment
      tags:
        - comment
      requestBody:
        content:
          application/json:
            schema:
              required:
                - content
              properties:
                content:
                  type: string
                  minLength: 20
                  maxLength: 6000
                  example:
                    Lorem ipsum dolor sit amet, consectetur adipiscing elit.
      responses:
        200:
          description: Return updated comment
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CommentResponse'
        400:
          description: BadReqest
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/400'
        401:
          $ref: '#/components/responses/401'
  /comments/{comment}/children:
    parameters:
      - $ref: '#/components/parameters/comment'
    get:
      summary: Get Comment children by Comment ID
      tags:
        - comment
      responses:
        200:
          description: Return Comment children
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Paginated'
                  - type: object
                    properties:
                      result:
                        type: array
                        items:
                          $ref: '#/components/schemas/CommentResponse'
  /citizens/{citizen}/comments/articles:
    parameters:
      - $ref: '#/components/parameters/citizen'
    get:
      security:
        - JWTAuth: []
      summary: all article comments for one citizen
      tags:
        - comment
        - article
        - citizen
      responses:
        200:
          description: Comments
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Paginated'
                  - type: object
                    properties:
                      result:
                        type: array
                        items:
                          $ref: '#/components/schemas/CommentResponse'
        401:
          $ref: '#/components/responses/401'
  /citizens/{citizen}/comments/constitutions:
    parameters:
      - $ref: '#/components/parameters/citizen'
    get:
      security:
        - JWTAuth: []
      summary: all constitution comments for one citizen
      tags:
        - comment
        - constitution
        - citizen
      responses:
        200:
          description: Comments
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Paginated'
                  - type: object
                    properties:
                      result:
                        type: array
                        items:
                          $ref: '#/components/schemas/CommentResponse'
        401:
          $ref: '#/components/responses/401'
  /constitutions/{constitution}/comments:
    parameters:
      - $ref: '#/components/parameters/constitution'
    get:
      summary: Get comment and children of one constitution
      tags:
        - comment
        - constitution
      parameters:
        - $ref: '#/components/parameters/page'
        - $ref: '#/components/parameters/limit'
        - $ref: '#/components/parameters/search'
        - name: sort
          in: query
          required: false
          example:
            - createdAt
            - votes
          schema:
            type: string
            default: createdAt
            enum:
              - createdAt
              - votes
      responses:
        200:
          description: Return Comment and children
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Paginated'
                  - type: object
                    properties:
                      result:
                        type: array
                        items:
                          $ref: '#/components/schemas/CommentResponse'
        400:
          description: BadReqest
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/400'
    post:
      security:
        - JWTAuth: []
      summary: Create Comment to constitution
      tags:
        - comment
        - constitution
      requestBody:
        content:
          application/json:
            schema:
              required:
                - content
              properties:
                content:
                  type: string
                  minLength: 20
                  maxLength: 6000
                  example:
                    Lorem ipsum dolor sit amet, consectetur adipiscing elit.
      responses:
        201:
          description: Return created comment
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CommentResponse'
        400:
          description: BadReqest
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/400'
        401:
          $ref: '#/components/responses/401'

  /constitutions:
    get:
      summary: Get all constitutions
      tags:
        - constitution
      operationId: getConstitutions
      parameters:
        - $ref: '#/components/parameters/page'
        - $ref: '#/components/parameters/limit'
        - $ref: '#/components/parameters/sort'
        - $ref: '#/components/parameters/direction'
        - $ref: '#/components/parameters/search'
      responses:
        200:
          description: The Constitution objects
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Paginated'
                  - type: object
                    properties:
                      result:
                        type: array
                        items:
                          $ref: '#/components/schemas/ConstitutionListingResponse'
        400:
          description: BadReqest
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/400'
    post:
      security:
        - JWTAuth: [ ]
      summary: Create new Constitution
      tags:
        - constitution
      operationId: insertConstitution
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ConstitutionRequest'

      responses:
        201:
          description: Constitution created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ConstitutionResponse'
        401:
          $ref: '#/components/responses/401'
        400:
          description: BadReqest
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/400'
  /constitutions/{constitution}:
    parameters:
      - $ref: '#/components/parameters/constitution'
    get:
      summary: Get all constitutions
      tags:
        - constitution
      operationId: getConstitutions
      responses:
        200:
          description: The Constitution objects
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ConstitutionResponse'

  /articles/{article}/follows:
    parameters:
      - $ref: '#/components/parameters/article'
    get:
      security:
        - JWTAuth: [ ]
      summary: Return Follow or nothing if you not follow
      tags:
        - follow
        - article
      responses:
        200:
          description: Return your follow
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FollowResponse'
        404:
          description: You not follow this article
    post:
      security:
        - JWTAuth: [ ]
      summary: Follow one article
      tags:
        - follow
        - article
      responses:
        201:
          description: Return only http status 201 on success
    delete:
      security:
        - JWTAuth: [ ]
      summary: Unfollow one article
      tags:
        - follow
        - article
      responses:
        204:
          description: Return only http status 204 on success
        401:
          $ref: '#/components/responses/401'
  /citizens/{citizen}/follows/articles:
    parameters:
      - $ref: '#/components/parameters/citizen'
    get:
      security:
        - JWTAuth: [ ]
      summary: Return Follow or nothing if you not follow
      tags:
        - follow
        - article
        - citizen
      responses:
        200:
          description: Return your follows
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Paginated'
                  - type: object
                    properties:
                      result:
                        type: array
                        items:
                          $ref: '#/components/schemas/FollowResponse'
  /constitutions/{constitution}/follows:
    parameters:
      - $ref: '#/components/parameters/constitution'
    get:
      security:
        - JWTAuth: [ ]
      summary: Return Follow or nothing if you not follow
      tags:
        - follow
        - constitution
      responses:
        200:
          description: Return your follow
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FollowResponse'
        404:
          description: You not follow this constitution
    post:
      security:
        - JWTAuth: [ ]
      summary: Follow one constitution
      tags:
        - follow
        - constitution
      responses:
        201:
          description: Return only http status 201 on success
        401:
          $ref: '#/components/responses/401'
    delete:
      security:
        - JWTAuth: [ ]
      summary: Unfollow one constitution
      tags:
        - follow
        - constitution
      responses:
        204:
          description: Return only http status 204 on success
        401:
          $ref: '#/components/responses/401'
  /citizens/{citizen}/follows/constitutions:
    parameters:
      - $ref: '#/components/parameters/citizen'
    get:
      security:
        - JWTAuth: [ ]
      summary: Return Follow or nothing if you not follow
      tags:
        - follow
        - constitution
        - citizen
      responses:
        200:
          description: Return your follows
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Paginated'
                  - type: object
                    properties:
                      result:
                        type: array
                        items:
                          $ref: '#/components/schemas/FollowResponse'

  /opinions:
    get:
      summary: Get all opinions choices
      tags:
        - opinion
      parameters:
        - in: query
          required: false
          name: targets
          description: opinion available for defined target
          example:
            - article
          schema:
            type: array
            items:
              type: string
      responses:
        200:
          description: return
          content:
            application/json:
              schema:
                description: Opinion Choice
                type: array
                items:
                  $ref: '#/components/schemas/OpinionChoice'
  /opinions/{opinion}:
    parameters:
      - $ref: '#/components/parameters/opinion'
    get:
      summary: Get one opinion Choices
      tags:
        - opinion
      responses:
        200:
          description: return
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OpinionChoice'
  /citizens/{citizen}/opinions:
    parameters:
      - $ref: '#/components/parameters/citizen'
    get:
      security:
        - JWTAuth: [ ]
      summary: Get all opinions of citizen filtered by target ids
      tags:
        - opinion
        - citizen
      parameters:
        - in: query
          required: true
          name: id
          description: target ids
          example:
            - 9226c1a3-8091-c3fa-7d0d-c2e98c9bee7b
          schema:
            type: array
            items:
              type: string
              format: uuid
      responses:
        200:
          description: Opinions
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Opinion'
  /citizens/{citizen}/opinions/articles:
    parameters:
      - $ref: '#/components/parameters/citizen'
    get:
      security:
        - JWTAuth: []
      summary: Get all opinions of one citizen
      tags:
        - opinion
        - citizen
      parameters:
        - $ref: '#/components/parameters/page'
        - $ref: '#/components/parameters/limit'
      responses:
        200:
          description: Opinions
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Paginated'
                  - type: object
                    properties:
                      result:
                        type: array
                        items:
                          $ref: '#/components/schemas/Opinion'
        400:
          description: BadReqest
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/400'

  /articles/{article}/opinions:
    parameters:
      - $ref: '#/components/parameters/article'
    put:
      security:
        - JWTAuth: []
      summary: Add Opinion on one article
      tags:
        - opinion
        - article
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                ids:
                  type: array
                  items:
                    type: string
                    format: uuid
                    example: 6e978eb5-3c48-0def-b093-e01f43983adb
      responses:
        201:
          description: Return the opinion
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Opinion'
        401:
          $ref: '#/components/responses/401'

  /constitutions/{constitution}/vote:
    parameters:
      - $ref: '#/components/parameters/constitution'
    put:
      security:
        - JWTAuth: [ ]
      summary: Vote for one constitution
      tags:
        - vote
        - constitution
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/VoteRequest'
      responses:
        201:
          description: Return only http status 201 on success
        400:
          description: BadReqest
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/400'
  /citizens/{citizen}/votes:
    parameters:
      - $ref: '#/components/parameters/citizen'
    get:
      security:
        - JWTAuth: [ ]
      summary: Get Citizen
      tags:
        - vote
        - citizen
      operationId: getCitizenVotes
      parameters:
        - name: id
          in: query
          required: true
          example:
            - 1329ab90-edae-cfed-f863-c8cb069fa327
            - cab54e50-ce85-bba0-da23-fc9f75feeaf5
          schema:
            type: array
            items:
              type: string
              format: uuid
      responses:
        200:
          description: The Votes objects
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/VoteResponse'
        404:
          description: Citizen not found
        401:
          $ref: '#/components/responses/401'
  /comments/{comment}/vote:
    parameters:
      - $ref: '#/components/parameters/comment'
    put:
      security:
        - JWTAuth: []
      summary: Vote for a comment
      tags:
        - vote
        - comment
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/VoteRequest'
      responses:
        201:
          description: Return votes aggregation
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/VoteAggregation'
        400:
          description: BadReqest
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/400'
        401:
          $ref: '#/components/responses/401'
  /citizens/{citizen}/votes/articles:
    parameters:
      - $ref: '#/components/parameters/citizen'
    get:
      security:
        - JWTAuth: [ ]
      summary: all article vote for one citizen
      tags:
        - vote
        - article
        - citizen
      parameters:
        - $ref: '#/components/parameters/page'
        - $ref: '#/components/parameters/limit'
      responses:
        200:
          description: Votes
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Paginated'
                  - type: object
                    properties:
                      result:
                        type: array
                        items:
                          $ref: '#/components/schemas/VoteResponse'
        400:
          description: BadReqest
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/400'
        401:
          $ref: '#/components/responses/401'
  /articles/{article}/vote:
    parameters:
      - $ref: '#/components/parameters/article'
    put:
      security:
        - JWTAuth: [ ]
      summary: Vote for one article
      tags:
        - vote
        - article
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/VoteRequest'
      responses:
        201:
          description: Return only http status 201 on success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/VoteAggregation'
        400:
          description: BadReqest
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/400'
        401:
          $ref: '#/components/responses/401'

  /workgroups:
    get:
      summary: Get all Workgroup (Paginated)
      tags:
        - workgroup
      parameters:
        - $ref: '#/components/parameters/page'
        - $ref: '#/components/parameters/limit'
        - $ref: '#/components/parameters/workgroupSort'
        - $ref: '#/components/parameters/direction'
        - $ref: '#/components/parameters/search'
        - $ref: '#/components/parameters/createdBy'
      responses:
        200:
          description: paginated list of workgroup
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Paginated'
                  - type: object
                    properties:
                      result:
                        type: array
                        items:
                          $ref: '#/components/schemas/WorkgroupListing'
        400:
          description: BadReqest
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/400'
    post:
      summary: Create new Workgroup
      security:
        - JWTAuth: [ ]
      tags:
        - workgroup
      requestBody:
        content:
          application/json:
            schema:
              required:
                - name
              properties:
                id:
                  type: string
                  format: uuid
                  nullable: true
                name:
                  type: string
                  example: Les partisants du RIC
                description:
                  type: string
                  example: Group formé pour la conception d'un RIC
                logo:
                  type: string
                  nullable: true
                anonymous:
                  type: boolean
                  example: false
                  nullable: true
                  default: true
      responses:
        201:
          description: Workgroup created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Workgroup'
        400:
          description: BadReqest
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/400'
  /workgroups/{workgroup}:
    parameters:
      - $ref: '#/components/parameters/workgroup'
    get:
      summary: Get one workgroup by ID
      tags:
        - workgroup
      responses:
        200:
          description: Workgroup
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Workgroup'
        404:
          description: Workshop not exist or are deleted
    put:
      summary: Edit one workgroup
      security:
        - JWTAuth: [ ]
      tags:
        - workgroup
      requestBody:
        content:
          application/json:
            schema:
              properties:
                name:
                  type: string
                  example: Les partisants du RIC
                description:
                  type: string
                  example: Group formé pour la conception d'un RIC
                logo:
                  type: string
                  nullable: true
                anonymous:
                  type: boolean
                  example: false
                  nullable: true
                  default: true
      responses:
        200:
          description: Workgroup updated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Workgroup'
        400:
          description: BadReqest
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/400'
    delete:
      summary: Delete one workgroup
      security:
        - JWTAuth: [ ]
      tags:
        - workgroup
      responses:
        204:
          description: Workgroup deleted
        404:
          description: Workshop not exist or are already deleted
  /workgroups/{workgroup}/members:
    parameters:
      - $ref: '#/components/parameters/workgroup'
    post:
      summary: Add members to the workgroup
      security:
        - JWTAuth: []
      tags:
        - workgroup
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/MembersRequest'
      responses:
        201:
          description: the list of members
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MembersResponse'
    put:
      summary: Updates ALL members.
      description: ⚠ PLEASE NOTE ⚠ This request removes all members who are not in request!
      security:
        - JWTAuth: []
      tags:
        - workgroup
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/MembersRequest'
      responses:
        200:
          description: the list of members
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MembersResponse'
        400:
          $ref: '#/components/responses/400'
    delete:
      summary: Delete members of workgroup
      security:
        - JWTAuth: []
      tags:
        - workgroup
      requestBody:
        content:
          application/json:
            schema:
              description: members of workgroup
              type: array
              items:
                type: object
                properties:
                  citizen:
                    required:
                      - id
                    properties:
                      id:
                        $ref: '#/components/schemas/UUID'
      responses:
        200:
          description: the list of members
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MembersResponse'
        400:
          $ref: '#/components/responses/400'

components:
  parameters:
    page:
      name: page
      in: query
      description: The current page
      example: 1
      required: false
      schema:
        default: 1
        type: integer
        minimum: 1
    limit:
      name: limit
      in: query
      description: The number of object per page
      example: 50
      required: false
      schema:
        default: 50
        type: integer
        minimum: 1
        maximum: 50
    sort:
      name: sort
      in: query
      description: The sort field name
      example: firstName
      required: false
      schema:
        type: string
    articleSort:
      name: sort
      in: query
      description: The sort field name
      example: createdAt
      required: false
      schema:
        type: string
        enum:
          - title
          - createdAt
          - vote
          - popularity
    citizenSort:
      name: sort
      in: query
      description: The sort field name
      example: createdAt
      required: false
      schema:
        type: string
        enum:
          - title
          - createdAt
    workgroupSort:
      name: sort
      in: query
      description: The sort field name
      example: createdAt
      required: false
      schema:
        type: string
        enum:
          - name
          - createdAt
    direction:
      name: direction
      in: query
      description: The sort direction
      example: asc
      required: false
      schema:
        type: string
        default: asc
        enum: [asc, desc]
    search:
      name: search
      in: query
      description: A text to seach
      example: content50
      required: false
      schema:
        type: string
    createdBy:
      name: createdBy
      in: query
      description: filter by Author
      example: 4d673bfa-eaef-4290-b52f-85a9c8a7eba5
      required: false
      schema:
        type: string
        format: uuid

    article:
      name: article
      in: path
      required: true
      description: the ID of article
      example: d91aa0cd-61d6-83cc-41bb-8d5656e130f7
      schema:
        type: string
        format: uuid

    citizen:
      name: citizen
      in: path
      description: ID of citizen
      example: 6434f4f9-f570-f22a-c134-8668350651ff
      required: true
      schema:
        type: string
        format: uuid

    comment:
      name: comment
      in: path
      description: The ID of comment
      example: 701dc504-db49-7e3a-2c0a-32542507ea57
      required: true
      schema:
        type: string
        format: uuid

    constitution:
      name: constitution
      in: path
      required: true
      description: the ID of constitution
      example: e74be8e4-6823-47c4-bd1b-789725b2fa8e
      schema:
        type: string
        format: uuid

    opinion:
      in: path
      required: true
      name: opinion
      description: Opinion ID
      example: 6e978eb5-3c48-0def-b093-e01f43983adb
      schema:
        type: string
        format: uuid

    workgroup:
      name: workgroup
      in: path
      description: ID of workgroup
      example: 82a0e60a-bb55-dbc0-1c3d-0a804df2b5df
      required: true
      schema:
        type: string
        format: uuid


  responses:
    401:
      description: Unautorized
      content:
        application/json:
          schema:
            description: noting
    400:
      description: BadReqest
      content:
        application/json:
          schema:
            description: noting

  schemas:
    UUID:
      type: string
      pattern: '[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}'
      description: UUID
      format: uuid
      example:
        e74be8e4-6823-47c4-bd1b-789725b2fa8e
    Paginated:
      required:
        - total
        - count
        - currentPage
        - limit
        - offset
        - result
      properties:
        result:
          type: array
          maxItems: 50
          items:
            required:
              - id
            properties:
              id:
                $ref: '#/components/schemas/UUID'
        count:
          type: integer
          minimum: 0
          example: 1
        currentPage:
          type: integer
          minimum: 0
          example: 1
        limit:
          type: integer
          minimum: 0
          maximum: 50
          example: 50
        offset:
          type: integer
          minimum: 0
          example: 1
        total:
          type: integer
          minimum: 0
          example: 1
    ArticleResponse:
      additionalProperties: false
      required:
        - id
        - versionId
        - versionNumber
        - title
        - anonymous
        - content
        - description
        - tags
        - draft
        - lastVersion
        - createdBy
        - views
        - opinions
        - votes
      properties:
        id:
          type: string
          format: uuid
        versionId:
          type: string
          format: uuid
        versionNumber:
          type: integer
          minimum: 0
        title:
          type: string
        anonymous:
          type: boolean
        content:
          type: string
        description:
          type: string
        tags:
          type: array
          items:
            type: string
        draft:
          type: boolean
        lastVersion:
          type: boolean
        createdAt:
          type: string
          format: 'date-time'
        createdBy:
          type: object
          additionalProperties: false
          required:
            - id
            - name
            - email
          properties:
            id:
              type: string
              format: uuid
            name:
              type: object
              required:
                - firstName
                - lastName
              properties:
                firstName:
                  type: string
                lastName:
                  type: string
            email:
              type: string
        workgroup:
          type: object
          nullable: true
          additionalProperties: false
          properties:
            id:
              type: string
              format: uuid
            name:
              type: string
        views:
          additionalProperties: false
          required:
            - total
            - unique
          properties:
            total:
              type: integer
            unique:
              type: integer
        opinions:
          additionalProperties:
            type: integer
          example:
            'good writed': 5
            'to short': 19
        votes:
          additionalProperties: false
          required:
            - up
            - neutral
            - down
            - total
            - score
          properties:
            up:
              type: integer
            neutral:
              type: integer
            down:
              type: integer
            total:
              type: integer
            score:
              type: integer
    ArticleListingResponse:
      required:
        - id
        - title
        - createdBy
        - workgroup
        - draft
      properties:
        id:
          type: string
          format: uuid
        title:
          type: string
        createdBy:
          $ref: '#/components/schemas/CitizenCreator'
        workgroup:
          type: object
          nullable: true
          additionalProperties: false
          properties:
            id:
              type: string
              format: uuid
            name:
              type: string
        draft:
          type: boolean

    CitizenListResponse:
      additionalProperties: false
      type: object
      required:
        - id
        - name
        - email
      properties:
        id:
          $ref: '#/components/schemas/UUID'
        name:
          type: object
          required:
            - firstName
            - lastName
          properties:
            firstName:
              type: string
              example:
                john
            lastName:
              type: string
              example:
                Doe
        email:
          type: string
          format: email
          example: my.email@dc-project.fr
    CitizenResponse:
      additionalProperties: false
      type: object
      required:
        - id
        - name
        - email
        - createdAt
        - user
      properties:
        id:
          $ref: '#/components/schemas/UUID'
        name:
          type: object
          required:
            - firstName
            - lastName
          properties:
            firstName:
              type: string
              example:
                john
            lastName:
              type: string
              example:
                Doe
        email:
          type: string
          format: email
          example: my.email@dc-project.fr
        birthday:
          type: string
          format: 'date'
          example: '1984-12-25'
        createdAt:
          type: string
          format: 'date-time'
        user:
          type: object
          required:
            - username
          properties:
            username:
              type: string
              example:
                john-doe
    CitizenCreator:
      additionalProperties: false
      type: object
      required:
        - id
        - name
        - user
      properties:
        id:
          $ref: '#/components/schemas/UUID'
        name:
          type: object
          required:
            - firstName
            - lastName
          properties:
            firstName:
              type: string
              example:
                john
            lastName:
              type: string
              example:
                Doe
        user:
          type: object
          required:
            - username
          properties:
            username:
              type: string
              example:
                john-doe

    CommentResponse:
      additionalProperties: false
      type: object
      required:
        - id
        - content
        - parent
        - createdAt
        - createdBy
        - votes
        - target
        - childrenCount
      properties:
        id:
          $ref: '#/components/schemas/UUID'
        content:
          type: string
          example:
            Lorem ipsum...
        parent:
          nullable: true
          properties:
            id:
              $ref: '#/components/schemas/UUID'
            reference:
              type: string
        createdBy:
          $ref: '#/components/schemas/CitizenCreator'
        createdAt:
          type: string
          format: 'date-time'
        updatedAt:
          type: string
          format: 'date-time'
        target:
          additionalProperties: false
          properties:
            id:
              $ref: '#/components/schemas/UUID'
            reference:
              type: string
        childrenCount:
          type: integer
          minimum: 0
        votes:
          properties:
            up:
              type: number
              minimum: 0
            neutral:
              type: number
              minimum: 0
            down:
              type: number
              minimum: 0
            total:
              type: number
              minimum: 0
            score:
              type: number
    ConstitutionRequest:
      additionalProperties: false
      description: The versionId field must be defined for update contitution
      type: object
      required:
        - title
      properties:
        id:
          $ref: '#/components/schemas/UUID'
        title:
          type: string
          minLength: 10
          maxLength: 80
          example:
            Constitution for the liberty
        titles:
          type: array
          default: [ ]
          items:
            additionalProperties: false
            type: object
            required:
              - name
            properties:
              id:
                $ref: '#/components/schemas/UUID'
              name:
                type: string
                minLength: 10
                maxLength: 80
                example:
                  The liberties
              articles:
                type: array
                items:
                  required:
                    - id
                  properties:
                    id:
                      $ref: '#/components/schemas/UUID'
        anonymous:
          type: boolean
          default: true
        draft:
          type: boolean
          default: false
        versionId:
          $ref: '#/components/schemas/UUID'
    ConstitutionResponse:
      additionalProperties: false
      type: object
      required:
        - id
        - title
        - titles
        - anonymous
        - draft
        - versionId
        - createdBy
        - createdAt
      properties:
        id:
          $ref: '#/components/schemas/UUID'
        title:
          type: string
          example:
            Constitution for the liberty
        titles:
          type: array
          default: [ ]
          items:
            additionalProperties: false
            type: object
            required:
              - id
              - name
              - rank
              - articles
            properties:
              id:
                $ref: '#/components/schemas/UUID'
              name:
                type: string
                example:
                  The liberties
              rank:
                type: integer
                minimum: 0
                example: 0
              createdBy:
                $ref: '#/components/schemas/CitizenCreator'
              createdAt:
                type: string
                format: 'date-time'
              articles:
                type: array
                items:
                  $ref: '#/components/schemas/ArticleListingResponse'
        anonymous:
          type: boolean
          default: true
        draft:
          type: boolean
          default: false
        versionId:
          $ref: '#/components/schemas/UUID'
        createdBy:
          $ref: '#/components/schemas/CitizenCreator'
        createdAt:
          type: string
          format: 'date-time'
    ConstitutionListingResponse:
      additionalProperties: false
      type: object
      required:
        - id
        - title
        - versionId
        - createdAt
        - createdBy
      properties:
        id:
          $ref: '#/components/schemas/UUID'
        title:
          type: string
          example:
            Constitution for the liberty
        versionId:
          $ref: '#/components/schemas/UUID'
        createdBy:
          $ref: '#/components/schemas/CitizenCreator'
        createdAt:
          type: string
          format: 'date-time'

    FollowResponse:
      additionalProperties: false
      required:
        - id
        - createdBy
        - createdAt
        - target
      properties:
        id:
          $ref: '#/components/schemas/UUID'
        createdBy:
          $ref: '#/components/schemas/CitizenCreator'
        createdAt:
          type: string
          format: 'date-time'
        target:
          required:
            - id
            - reference
          additionalProperties: false
          properties:
            id:
              $ref: '#/components/schemas/UUID'
            reference:
              type: string

    OpinionChoice:
      description: Opinion Choice
      type: object
      required:
        - name
      properties:
        id:
          type: string
          format: uuid
        name:
          type: string
          example: opinion1
        target:
          type: array
          nullable: true
          items:
            type: string
            description: the name of the target
    Opinion:
      description: Opinion
      type: object
      properties:
        id:
          type: string
          format: uuid
        name:
          type: string
          example: opinion1
        target:
          type: object
          properties:
            id:
              type: string
              format: uuid
            reference:
              type: string
              example: article
        choice:
          type: object
          allOf:
            - $ref: '#/components/schemas/OpinionChoice'
        reference:
          type: string
          example: opinion_on_article
        createdBy:
          $ref: '#/components/schemas/CitizenCreator'
        createdAt:
          type: string
          format: 'date-time'

    VoteRequest:
      type: object
      additionalProperties: false
      required:
        - note
      properties:
        note:
          type: integer
          minimum: -1
          maximum: 1
    VoteResponse:
      type: object
      additionalProperties: false
      required:
        - id
        - note
        - createdAt
        - createdBy
        - target
      properties:
        id:
          $ref: '#/components/schemas/UUID'
        note:
          type: integer
          minimum: -1
          maximum: 1
        createdAt:
          type: string
          format: 'date-time'
        createdBy:
          $ref: '#/components/schemas/CitizenCreator'
        target:
          required:
            - id
            - reference
          properties:
            id:
              $ref: '#/components/schemas/UUID'
            reference:
              type: string
    VoteAggregation:
      additionalProperties: false
      type: object
      required:
        - up
        - neutral
        - down
        - total
        - score
        - updatedAt
      properties:
        up:
          type: number
          minimum: 0
        neutral:
          type: number
          minimum: 0
        down:
          type: number
          minimum: 0
        total:
          type: number
          minimum: 0
        score:
          type: number
        updatedAt:
          type: string
          format: 'date-time'

    WorkgroupListing:
      description: Workgroup
      type: object
      properties:
        id:
          type: string
          format: uuid
        name:
          type: string
          example: Les partisants du RIC
        description:
          type: string
          example: Group formé pour la conception d'un RIC
        logo:
          type: string
          nullable: true
    Workgroup:
      description: Workgroup
      type: object
      required:
        - id
        - name
        - description
        - logo
        - anonymous
        - createdBy
        - members
      properties:
        id:
          type: string
          format: uuid
        name:
          type: string
          example: Les partisants du RIC
        description:
          type: string
          example: Group formé pour la conception d'un RIC
        logo:
          type: string
          nullable: true
        anonymous:
          type: boolean
        createdBy:
          $ref: '#/components/schemas/CitizenCreator'
        members:
          $ref: '#/components/schemas/MembersResponse'

    MembersRequest:
      description: members of workgroup
      type: array
      items:
        type: object
        properties:
          citizen:
            required:
              - id
            properties:
              id:
                $ref: '#/components/schemas/UUID'
          roles:
            type: array
            items:
              type: string
              enum:
                - MASTER
                - MANAGER
                - EDITOR
                - REPORTER
              example: MASTER
    MembersResponse:
      description: members of workgroup
      type: array
      items:
        description: Member of workgroup
        type: object
        properties:
          citizen:
            $ref: '#/components/schemas/CitizenCreator'
          roles:
            type: array
            items:
              type: string
              enum:
                - MASTER
                - MANAGER
                - EDITOR
                - REPORTER
              example: MASTER

    400:
      description: Bad Request
      required:
        - title
        - invalidParams
      additionalProperties: false
      properties:
        statusCode:
          type: integer
          example: 400
        title:
          type: string
          example: Bad Request
        invalidParams:
          type: array
          items:
            required:
              - name
              - reason
            properties:
              name:
                type: string
                example: '.title'
              reason:
                type: string
                example: 'Cannot be null'

    404:
      description: Not Found
      required:
        - title
        - statusCode
      additionalProperties: false
      properties:
        statusCode:
          type: integer
          example: 404
        title:
          type: string
          example: Bad Request

  securitySchemes:
    JWTAuth:
      type: http
      scheme: bearer
      description: call /login to get token
      bearerFormat: JWT

servers:
  - description: localhost
    url: http://localhost:8080
  - description: production
    url: http://dc-project.fr