# Dokumentacja API
RobocikHub and Apps REST API + socket.io events docs.
## Notations
This file is based on some shorthanded notations as to avoid repetition and long walls of text explaining that something is based on a condition.
- [type] - data type (int / bool / str / obj / {Obj} / [type] arr)
- {Obj [id] (condition)} - previously defined group of fields (sort of like a JS object or a schema); `[id]` is an optional indentifier of an object's record in the database
- {Obj -field1 -field2(condition)} - which fields are not included
- {Obj +field1 +field2(condition)} - which fields are included (and only those)
- (condition) - an optional condition (written sort of like conditions in JS) which decides either:
- whether the given Obj record should be accessible\
*example*: <small>`(_.field==value)`</small> or <small> `({OtherObj [_.idOtherObj]}.field==value)`</small> - whether the record should be accessible based on it's field OR another Object's field\
(`_` represents a specific (based on context) record in a database)
- whether a "field inclusion rule" should be respected for a given Obj record\
*example*: <small>`+field1(_.field2)`</small> - whether to include a field based on another field
## REST API
Each route begins with `/api`.
### Usually HTTP methods correspond to CRUD actions
`C` POST | `R` GET | `U` PUT, PATCH | `D` DELETE
The difference between PUT and PATCH is that with PUT the update should include all fields (like POST) to effectively replace the old record, while PATCH only updates the specified fields.\
*Example*:\
User <small>`{ id: 1, name: 'Lorem', surname: 'Ipsum'}`</small>\
`PUT` /users <small>`{ id: 1, name: 'Dolor', surname: 'Sit'}`</small>\
`PATCH` /users/surname <small>`{ id: 1, surname: 'Amet'}`</small>
### Routes can take 3 types of parameters
- (path) in the url path\
<small>`/api/users/:id`</small> | parametr <small>`id`</small>
- (url) as url parameters\
<small>`/api/users/amount=xxx?page=xxx`</small> | parametry <small>`amount`</small>, <small>`page`</small>
- (query) json parameters in the query\
<small>`/api/auth/login`</small>, <small>`{ email: "xxx", password: "xxx"}`</small> | parametry <small>`email`</small>, <small>`password`</small>
### Each request should TAKE some or all of these parameters
- (query) `token` [str] JWT authorization token
- (path) `amount` [int] how many elements on each page (defaults to 50)
- (path) `page` [int] which page, 1-indexed (defaults to 1)
### Each request should RETURN some or all of these parameters
- `error` [str] error description, should be user-readable
- `errorDetails` [obj] based on the type of error this can be a more in depth description or directly return the error object
- `data` [obj] the response data
- `info` [obj] additional information about a collection if applicable
- `count` [int] amount of items in the table
**Whether the call was successful is derived from the status.**
In each undermentioned route the `data` element corresponds to the above `data` parameter.
## routes
### `/census`
Authentication and authorization service. Uses **JWT**s as sessions.
|User|
|-|
- `id` [int]
- `admin` [bool]
- `first_name` [str]
- `last_name` [str]
- `photo` [str] photo token
- `emails` [str]
- `school` [str]
- `faculty` [str]
- `field_of_study` [str]
- `divisions` [object] chosen from a list
- `specialty` [str]
- `linkedin` [str] url
- `github` [str] url
- `gitlab` [str] url
- `about_me` [str]
- `quote` [str]
- `consent_rodo` [bool] basically mandatory, other data cannot be inserted if this is false
- `consent_website` [bool] whether certain data should be shared on a website
#### `POST` /login
Log in the user using email and password.
- params (query)
- `email` [str]
- `password` [str]
- data
- {User +id}
#### `GET` /logout
#### `GET` /me
Current user info.
- data
- {User -id}
### `/votum`
|User|
|-|
- `id` [int]
- `idCensus` [int] 1-1 relationship with the main Census profile
- `admin` [bool]
- `rightToVote` [bool] whether the user has voting rights
|Question|
|-|
- `id` [int]
- `title` [str]
- `timeOpen` [str] opening time (ISO 8601)
- `timeClose` [str] closing time (ISO 8601)
- `showResults` [bool] whether to show the voting results (answers and counts)
- `maxAnswers` [int] maximum amount of answers that can be chosen for this question
|Answer|
|-|
- `id` [int]
- `idQuestion` [int] 1-1 relationship with Question
- `title` [str]
- `votes` [int] how many votes were cast for this answer
### /votum/users
#### `POST` /users <small>admin</small>
Create a user.
- params (query)
- {User -id}
#### `GET` /users <small>admin</small>
Read all users.
- data [arr]
- {User}
#### `GET` /users/:id <small>admin</small>
Read a single user.
- params (path)
- `id` [int]
- data
- {User}
#### `PUT` /users <small>admin</small>
Update a single user.
- params (query)
- {User}
#### `PATCH` /users/:id/rightToVote <small>admin</small>
Update a single user's rightToVote field.
- params (path)
- `id` [int]
- params (query)
- `id` [int]
- `rightToVote` [bool]
#### `DELETE` /users <small>admin</small>
Delete a single user.
- params (query)
- {Question +id}
### /votum/questions
#### `POST` /questions <small>admin</small>
Create a question.
- params (query)
- {Question -id}
#### `GET` /questions
Read all questions and their answers.
- data [arr]
- {Question (_.timeOpen < Date.now() < _.timeClose)}
- `answers` [{Answer -idQuestion -votes({Question [_.idQuestion]}.showResults)} arr] answers for the given question
- `userVoted` [bool] whether the current user has already voted on this question
#### `GET` /questions <small>admin</small>
Read all questions and their answers.
- data [arr]
- {Question}
- `answers` [{Answer -idQuestion -votes({Question [_.idQuestion]}.showResults)} arr] answers for the given question
- `userVoted` [bool] whether the current user has already voted on this question
#### `GET` /questions/:id
Read a single question and it's answers.
- params (path)
- `id` [int]
- data
- {Question (_.timeOpen < Date.now() < _.timeClose)}
- `answers` [{Answer -idQuestion -votes({Question [_.idQuestion]}.showResults)} arr] answers for the given question
- `userVoted` [bool] whether the current user has already voted on this question
#### `GET` /questions/:id <small>admin</small>
Read a single question and it's answers.
- params (path)
- `id` [int]
- data
- {Question}
- `answers` [{Answer -idQuestion -votes(Question.showResults)} arr] answers for the given question
- `userVoted` [bool] whether the current user has already voted on this question
#### `PUT` /questions <small>admin</small>
Update a single question and it's answers.
- params (query)
- {Question}
- `answers` [{Answer -votes} arr] answers for the given question
#### `PATCH` /questions/:id/showResults <small>admin</small>
Update a single question's showResults field.
- params (path)
- `id` [int]
- params (query)
- {Question +showResults}
#### `DELETE` /questions <small>admin</small>
Delete a single question and it's answers.
- params (query)
- {Question +id}
### /votum/vote
#### `POST` /vote
- params (query)
- `idQuestion` [int]
- `idsAnswers` [[int] arr]
## socket.io
#### `questions`
Sent on each `GET`, `PUT`, `PATCH`, `DELETE` /questions call.\
Sent on each `POST` /vote call.
- data (`GET` /questions)
#### `adminQuestions`
Sent on each `POST`, `PUT`, `PATCH`, `DELETE` /questions call.\
Sent on each `POST` /vote call.
- data (`GET` /questions <small>admin</small>)
#### `adminUsers`
Sent on each `GET`, `PUT`, `PATCH`, `DELETE` /users call.
- data (`GET` /users <small>admin</small>)