You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
mv-api-spec/mv-openapi.yaml

693 lines
21 KiB

# Warning: this file has been automatically generated. All manual modifications will be lost, see README.md for details.
openapi: 3.0.0
info:
title: API Mieux Voter
description: "## What is this?\n\nAn _Application Programming Interface_ (API) for a polling application\nusing **Majority Judgment**.\n\nYou are looking at the specifications of the communication between server and clients, usually because you want to make your own client.\n\n### Help, I'm lost!\n\nBest head to the official application client, then:\n[Application MieuxVoter](https://app.mieuxvoter.fr).\nSee you there !\n\n\n## What is Majority Judgment?\n\nWe believe that it is the most elegant polling system that is available right now.\n\nIt was discovered in 2002 by \U0001F1EB\U0001F1F7 french researchers, and it comes from \U0001F377 wine \U0001F3C6 contests.\n\n\n## Contributing\n\n### I've found a bug!\n\nHead over to our [issues tracker](https://github.com/MieuxVoter/mv-api-spec/issues) with your ideas and contributions.\n\n### But I don't understand code!\n\nIt's okay, we need everyone!\nThere's lots you can do to help, such as translating, documenting, reporting issues, painting pixels, promoting majority judgment…\n\n### Shut up and take my money!\n\nDonations help us boost development : [Donate](https://mieuxvoter.fr/index.php/participer/).\n"
version: 1.0.1-oas3
termsOfService: 'https://github.com/MieuxVoter'
contact:
name: Mieux Voter App Development Team
email: app@mieuxvoter.fr
servers:
- url: 'https://api.mieuxvoter.fr/v1'
description: Main (production) server
- url: 'https://sandboxapi.mieuxvoter.fr/v1'
description: Internal staging server for testing
paths:
/polls:
get:
operationId: get-polls
summary: Gets all polls
responses:
'200':
description: OK
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/poll'
post:
operationId: create-poll
summary: Creates a poll
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/poll'
responses:
'201':
description: Created
content:
application/json:
schema:
type: object
properties:
id:
type: string
description: Id of the created poll.
links:
get-poll:
$ref: '#/components/links/get-poll'
update-poll:
$ref: '#/components/links/update-poll'
delete-poll:
$ref: '#/components/links/delete-poll'
create-ballot:
$ref: '#/components/links/create-ballot'
list-poll-results:
$ref: '#/components/links/list-poll-results'
'400':
description: Bad Request. Provide at least 2 proposals and a title.
'/polls/{poll-id}':
parameters:
- in: path
name: poll-id
required: true
schema:
type: integer
format: int64
get:
operationId: get-poll
summary: Gets a poll by ID
responses:
'200':
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/poll'
'404':
$ref: '#/components/responses/poll-not-found'
patch:
operationId: update-poll
summary: Updates a poll
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/poll'
security:
- {}
- pollAuth: []
responses:
'200':
description: Poll was updated.
content:
application/json:
schema:
$ref: '#/components/schemas/poll'
'404':
$ref: '#/components/responses/poll-not-found'
delete:
operationId: delete-poll
summary: Deletes a poll
description: >
All the Poll data will be permanently erased. This includes all the
corollary models (Tally, Ballots, …) Only the Poll's author may delete
it. (and wild admins)
responses:
'200':
description: Poll was deleted.
'404':
$ref: '#/components/responses/poll-not-found'
security:
- pollAuth: []
'/polls/{poll-id}/ballots':
parameters:
- in: path
name: poll-id
required: true
schema:
type: string
post:
operationId: create-ballot
summary: Creates a ballot
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/ballot'
security:
- {}
- participantAuth: []
responses:
'201':
description: Created
content:
application/json:
schema:
type: object
properties:
id:
type: string
description: Id of the created ballot.
links:
get-ballot:
$ref: '#/components/links/get-ballot'
delete-ballot:
$ref: '#/components/links/delete-ballot'
'/polls/{poll-id}/ballots/{ballot-id}':
parameters:
- in: path
name: poll-id
required: true
schema:
type: string
- in: path
name: ballot-id
required: true
schema:
type: string
get:
operationId: get-ballot
summary: Gets a ballot by ID
responses:
'200':
description: A ballot object
content:
application/json:
schema:
$ref: '#/components/schemas/ballot'
delete:
operationId: delete-ballot
summary: Deletes a ballot
responses:
'200':
description: OK
'404':
$ref: '#/components/responses/ballot-not-found'
security:
- participantAuth: []
'/polls/{poll-id}/participants':
parameters:
- in: path
name: poll-id
required: true
schema:
type: string
post:
operationId: add-participant-to-poll
summary: Adds a participant to a poll
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/participant'
responses:
'200':
description: Invitation was sent.
content:
text/plain:
schema:
type: string
'404':
$ref: '#/components/responses/poll-not-found'
'/polls/{poll-id}/participants/{participant-id}/':
parameters:
- in: path
name: participant-id
required: true
schema:
type: string
get:
operationId: get-poll-participant
summary: Gets a participant from a poll
responses:
'200':
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/participant'
'404':
$ref: '#/components/responses/participant-not-found'
security:
- {}
- pollAuth: []
delete:
operationId: delete-poll-participant
summary: Deletes a participant from a poll
responses:
'200':
description: OK
'404':
$ref: '#/components/responses/participant-not-found'
security:
- pollAuth: []
'/polls/{poll-id}/results':
parameters:
- in: path
name: poll-id
required: true
schema:
type: string
get:
operationId: get-poll-results
summary: Gets results of a poll
responses:
'200':
description: OK
content:
text/plain:
schema:
$ref: '#/components/schemas/result'
'404':
$ref: '#/components/responses/poll-not-found'
/users:
get:
operationId: get-users
summary: Gets all users.
responses:
'200':
description: OK
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/user'
post:
operationId: create-user
summary: Creates an user
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/user'
responses:
'201':
description: Created
content:
application/json:
schema:
type: object
properties:
id:
type: string
description: Id of the created user.
links:
get-user:
$ref: '#/components/links/get-user'
update-user:
$ref: '#/components/links/update-user'
delete-user:
$ref: '#/components/links/delete-user'
'/users/{user-id}':
parameters:
- in: path
name: user-id
required: true
schema:
type: integer
format: int64
get:
operationId: get-user
summary: Gets a user by ID
responses:
'200':
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/user'
'404':
$ref: '#/components/responses/user-not-found'
patch:
operationId: update-user
summary: Updates a user
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/user'
security:
- {}
- userAuth: []
responses:
'200':
description: OK
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/user'
delete:
operationId: delete-user
summary: Deletes a user
responses:
'200':
description: OK
'404':
$ref: '#/components/responses/user-not-found'
security:
- userAuth: []
components:
securitySchemes:
participantAuth:
type: http
scheme: bearer
pollAuth:
type: http
scheme: bearer
resultAuth:
type: http
scheme: bearer
userAuth:
type: http
scheme: bearer
schemas:
ballot:
type: object
properties:
id:
type: integer
description: A unique identifier
example: 4
readOnly: true
grade:
type: integer
description: >
One grade of the grading defined when creating the poll. Zero (0)
means the worst grade, and it goes upwards from there, up to the
size of the grading, minus one.
example: 2
proposal:
type: object
properties:
id:
readOnly: true
type: integer
description: >
A unique identifier for the proposal, in the context of the poll.
This is not a globally unique identifier.
example: 4
uuid:
readOnly: true
type: string
format: uuid
description: |
A Universally Unique IDentifier for the proposal. (UUIDv4)
example: fa888652-727e-470b-817e-d77862a8d112
name:
type: string
description: |
Unique but short name of the proposal. No markup is allowed.
example: A new school
description:
type: string
description: >
An optional, multiline description of the proposal. Commonmark
markdown is allowed.
example: This school would welcome 500 pupils.
ballots:
type: array
description: >
The ballots received by this proposal. Each participant may emit one
ballot (one judgment) per proposal.
items:
$ref: '#/components/schemas/ballot'
required:
- name
grade:
type: object
properties:
id:
type: integer
description: >
Unique identifier of the grade in its grading. Zero (0) is the worst
grade, and it goes upwards.
example: 0
readOnly: true
name:
type: string
description: |
Unique but short name of the grade, like "Excellent" or "To reject".
example: Good
description:
type: string
description: An optional description of the grade.
example: 'In this poll, the grade "To reject" disqualifies the proposal.'
required:
- name
participant:
type: object
properties:
id:
readOnly: true
type: string
description: A unique identifier.
example: JtRm05yjMAuFCI2uwnFp
name:
type: string
maxLength: 32
description: An optional name or pseudonym for the participant.
example: Jane Doe
email:
type: string
description: >
The electronic mail address that will eventually be created at the
creation of the participant (not kept in memory).
example: jane.doe@example.com
has-participated:
type: boolean
description: >-
True if the participant already participated to the poll, False
otherwise
example: true
poll-id:
type: string
description: The identifier of the poll that the participant participates on.
example: 1jDe1e5eF_IkaYPuoIYX
user-id:
type: string
description: The identifier of the user.
example: 1jDe1e5eF_IkaYPuoIYX
required:
- poll-id
poll:
type: object
description: >
A `Poll` is the core model of the application.
A `Poll` exposes a list of `Proposal`s, and `Participant`s may
individually give each `Proposal` a `Grade`. (in a `Ballot`)
properties:
id:
type: string
description: A unique identifier.
example: 1jDe1e5eF_IkaYPuoIYX
readOnly: true
uuid:
type: string
format: uuid
pattern: '[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}'
description: |
A Universally Unique IDentifier for the poll. (version 4)
example: bb788552-727d-470b-827e-d7796248d293
readOnly: true
title:
type: string
description: The title of the poll.
example: What project should our neighbourhood invest in for the next year?
description:
type: string
description: >
A lengthy description of the poll. In here should be stated the
constitutive details of the poll, whether it is informative or
imperative for example.
example: >
This poll will help decide which projects get the most attention and
budget so you should consider the proposals carefully and with
gumption.
proposals:
type: array
description: >
The proposals being judged by the participants in a poll. It makes
no sense to have less than two proposals in a poll.
minItems: 2
maxItems: 20
items:
$ref: '#/components/schemas/proposal'
grades:
type: array
description: The grades on which one participant vote to a proposal.
minItems: 2
maxItems: 10
items:
$ref: '#/components/schemas/grade'
participants:
type: array
description: The participants that are allowed to participate to the election.
items:
$ref: '#/components/schemas/participant'
user-id:
type: string
description: 'Organizer id. If not given, a dummy user is created.'
restrict-participants:
type: boolean
description: 'True if anyone can participate in this poll, False otherwise.'
example: false
required:
- title
- proposals
error:
type: object
properties:
code:
type: string
description: The HTTP code of the response
example: 404
message:
type: string
description: The response details
example: The specified participant was not found
required:
- code
- message
result:
type: object
properties:
poll:
$ref: '#/components/schemas/poll'
ranking:
type: array
description: >-
An array representing grades level for each proposal, according to
the grades list, following the order of the proposals array defined
when the related poll has been created.
example:
- 0
- 6
- 3
- 2
- 2
minItems: 2
maxItems: 20
items:
type: integer
format: int16
required:
- ranking
- poll
user:
type: object
properties:
id:
type: integer
description: A unique identifier
example: 0
readOnly: true
name:
type: string
description: Unique user-name
example: john.doe
description:
type: string
description: An optional description of the user
example: >-
John Doe is a multiple-use name that is used when the true name of a
person is unknown or is being intentionally concealed
links:
get-poll:
operationId: get-poll
parameters:
pollId: $response.body#/id
description: >
The `id` value returned in the response can be used as the `poll-id`
parameter in GET /polls/{poll-id}.
update-poll:
operationId: update-poll
parameters:
pollId: $response.body#/id
description: >
The `id` value returned in the response can be used as the `poll-id`
parameter in PATCH /polls/{poll-id}.
delete-poll:
operationId: delete-poll
parameters:
pollId: $response.body#/id
description: >
The `id` value returned in the response can be used as the `poll-id`
parameter in DELETE /polls/{poll-id}.
create-ballot:
operationId: create-ballot
parameters:
userId: $response.body#/id
description: >
The `id` value returned in the response can be used as the `poll-id`
parameter in POST /polls/{poll-id}/ballots.
list-poll-results:
operationId: list-poll-results
parameters:
pollId: $response.body#/id
description: >
The `id` value returned in the response can be used as the `poll-id`
parameter in GET /polls/{poll-id}/results.
get-ballot:
operationId: get-ballot
parameters:
ballotId: $response.body#/id
description: >
The `id` value returned in the response can be used as the `ballot-id`
parameter in GET /polls/{poll-id}/ballots/{ballot-id}.
delete-ballot:
operationId: delete-ballot
parameters:
ballotId: $response.body#/id
description: >
The `id` value returned in the response can be used as the `ballot-id`
parameter in DELETE /polls/{poll-id}/ballots/{ballot-id}.
get-user:
operationId: get-user
parameters:
userId: $response.body#/id
description: >
The `id` value returned in the response can be used as the `user-id`
parameter in GET /users/{user-id}.
update-user:
operationId: update-user
parameters:
userId: $response.body#/id
description: >
The `id` value returned in the response can be used as the `user-id`
parameter in PATCH /users/{user-id}.
delete-user:
operationId: delete-user
parameters:
userId: $response.body#/id
description: >
The `id` value returned in the response can be used as the `user-id`
parameter in DELETE /users/{user-id}.
responses:
poll-not-found:
description: The specified poll was not found
content:
application/json:
schema:
$ref: '#/components/schemas/error'
ballot-not-found:
description: The specified ballot was not found
content:
application/json:
schema:
$ref: '#/components/schemas/error'
participant-not-found:
description: The specified participant was not found
content:
application/json:
schema:
$ref: '#/components/schemas/error'
user-not-found:
description: The specified user was not found
content:
application/json:
schema:
$ref: '#/components/schemas/error'