Massively extend documentation
This commit is contained in:
parent
02845e65db
commit
2068dfd1af
55
README.md
55
README.md
|
@ -1,5 +1,40 @@
|
|||
# Candymat - Wahl-o-Mat fuer Personalwahlen
|
||||
|
||||
## Introduction
|
||||
|
||||
The candymat is a Wahl-o-Mat for elections of candidates.
|
||||
|
||||
|
||||
## Services
|
||||
|
||||
The project consists of three services:
|
||||
* GraphQL backend (+ postgres)
|
||||
* Redaktions-App
|
||||
* User-App
|
||||
|
||||
### Redaktions-App
|
||||
|
||||
The Redaktions-App is used for editors and candidates to provide questions and answers.
|
||||
|
||||
The app is written with react and appollo-react to access the backend.
|
||||
|
||||
See also: [Service Readme](redaktions-app/README.md)
|
||||
|
||||
### User-App
|
||||
|
||||
The User-App is based on the [EuroMat](https://www.euromat.info/en) (Source: https://github.com/morkro/euromat)
|
||||
and is used to find the perfect candidate for everyone who is allowed to vote.
|
||||
|
||||
It is written in vue.js.
|
||||
|
||||
See also: [Service Readme](https://git.verdigado.com/Netzbegruenung/candymat-user-app/src/README.md)
|
||||
|
||||
### Postgraphile (Backend)
|
||||
|
||||
A package which creates an GraphQL api based on an underlying postgres schema.
|
||||
|
||||
For more on this (e.g. how to use the graphQl api by yourself) see [backend readme](backend/README.md)
|
||||
|
||||
## Development Setup
|
||||
|
||||
### Check-out repository
|
||||
|
@ -12,16 +47,22 @@
|
|||
|
||||
### Start the services
|
||||
|
||||
```docker-compose up -d``` for dev setup.
|
||||
The database will use a volume to persist changes in-between runs.
|
||||
To start with a clean database, either delete the volume from the postgres configuration in the compose file
|
||||
or run ```docker volume rm candymat_db-data``` before starting the containers.
|
||||
|
||||
|
||||
### Where to access the services
|
||||
For dev setup:
|
||||
```
|
||||
docker-compose up
|
||||
```
|
||||
|
||||
* GraphQL IDE/GUI: http://localhost:5433/graphiql
|
||||
* GraphQL Endpoint: http://localhost:5433/graphql
|
||||
* UserApp: http://localhost:8080
|
||||
* RedaktionsApp: http://localhost:8081
|
||||
* Postgres database: http://localhost:5432
|
||||
|
||||
**Note:** The database will use a volume to persist changes in-between runs.
|
||||
To start with a clean database, either delete the volume from the postgres configuration in the compose file
|
||||
or run
|
||||
```
|
||||
docker container rm candymat_postgres_1
|
||||
docker volume rm candymat_db-data
|
||||
```
|
||||
before starting docker-compose.
|
||||
|
|
|
@ -1,11 +1,197 @@
|
|||
# Candymat Backend
|
||||
|
||||
## Setup dev environment
|
||||
The candymat backend consists of a postgres database and a [postgraphile](https://www.graphile.org/postgraphile/introduction/) instance.
|
||||
Postgraphile generates a Graphql backend based on the underlying postgres schema.
|
||||
|
||||
### Postgres via Docker
|
||||
missing
|
||||
## Introduction
|
||||
|
||||
### Postgres on your machine
|
||||
* Install postgres and start it
|
||||
* Create a new database
|
||||
* Execute the scripts in the `./sql` folder in chronological order
|
||||
### Basic structure
|
||||
|
||||
There are three "data" tables:
|
||||
* category
|
||||
* question
|
||||
* answer
|
||||
|
||||
Questions can belong to categories.
|
||||
Answers belong to questions and candidates.
|
||||
|
||||
### User management
|
||||
|
||||
There are four types of roles:
|
||||
* editor
|
||||
* candidate
|
||||
* user
|
||||
* anonymous
|
||||
|
||||
Editors handle questions and categories, candidates handle their specific answers and users are only important
|
||||
in setups where there is no public access to the data.
|
||||
|
||||
#### Authentication
|
||||
|
||||
Authentication is handled via jwt.
|
||||
The candymat setup roughly follows the instructions in the [postgraphile docu](https://www.graphile.org/postgraphile/postgresql-schema-design/#authentication-and-authorization).
|
||||
|
||||
## Manually test the backend
|
||||
|
||||
To test the backend manually an (enhanced) graphiql instance is started in dev mode.
|
||||
To access it navigate to http://localhost:5433/graphiql.
|
||||
|
||||
#### Authenticate (or how to pose as a member of one of the roles)
|
||||
|
||||
To pose as one of the three roles authenticate as
|
||||
* `erika@musterman.de` (editor)
|
||||
* `max@mustermann.de` (candidate)
|
||||
* `happy@user.de` (normal user)
|
||||
|
||||
The password is always "password".
|
||||
|
||||
Use following graphQL mutation to get the jwtToken of an editor:
|
||||
```
|
||||
mutation Authenticate {
|
||||
__typename
|
||||
authenticate(input: {email: "erika@mustermann.de", password: "password"}) {
|
||||
jwtToken
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The jwtToken in the response has to be added to the headers in the following way:
|
||||
```
|
||||
{
|
||||
"Authorization": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoiY2FuZHltYXRfY2FuZGlkYXRlIiwicGVyc29uX2lkIjoyLCJleHAiOjE1OTEwNDgzMzgsImlhdCI6MTU5MDg3NTUzNywiYXVkIjoicG9zdGdyYXBoaWxlIiwiaXNzIjoicG9zdGdyYXBoaWxlIn0.21Lu51_suJ5O2RU-UKN2Y6fvKw4SYe-oqx_QqlU0-GE"
|
||||
}
|
||||
```
|
||||
|
||||
#### Query the data tables
|
||||
|
||||
This is possible as member of any role, including no role (anonymous).
|
||||
|
||||
You can use the schema to get familiar with possible queries.
|
||||
As an example, here is a query which retrieves all questions including the category they belong to:
|
||||
```graphql
|
||||
{
|
||||
allQuestions {
|
||||
nodes {
|
||||
categoryByCategoryId {
|
||||
title
|
||||
description
|
||||
}
|
||||
text
|
||||
description
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
Example response:
|
||||
```json
|
||||
{
|
||||
"data": {
|
||||
"allQuestions": {
|
||||
"nodes": [
|
||||
{
|
||||
"categoryByCategoryId": {
|
||||
"title": "Umwelt",
|
||||
"description": "Themen rund um Naturschutz usw."
|
||||
},
|
||||
"text": "Was sagen Sie zur 10H Regel?",
|
||||
"description": "In Bayern dürfen Windräder nur ..."
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Creating new users
|
||||
|
||||
aka "register"
|
||||
|
||||
Only possible if no bearer token is set in the headers.
|
||||
```graphql
|
||||
mutation Register {
|
||||
registerPerson(input: {firstName: "Ford", lastName: "Prefect", email: "ford@prefect.com", password: "password"}) {
|
||||
person {
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Creating questions
|
||||
|
||||
This is only possible as "editor". Use the following mutation:
|
||||
```
|
||||
mutation CreateQuestion($text: String!) {
|
||||
createQuestion(input: {question: {text: $text}}) {
|
||||
question {
|
||||
text
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
with the variables
|
||||
```
|
||||
{
|
||||
"text": "Die Antwort auf die Frage nach dem Leben, dem Universum und dem ganzen Rest?"
|
||||
}
|
||||
```
|
||||
|
||||
#### Creating categories
|
||||
|
||||
This is only possible as "editor".
|
||||
|
||||
Mutation:
|
||||
```
|
||||
mutation CreateCategory($title: String!) {
|
||||
createCategory(input: {category: {title: $title}}) {
|
||||
category {
|
||||
title
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Variables
|
||||
```
|
||||
{
|
||||
"title": "Verkehr"
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
##### Creating answers
|
||||
|
||||
This is only possible as "candidate".
|
||||
Also the `personId` needs to be `2` (the id of Max Mustermann).
|
||||
It is impossible for a candidate to pose as a different candidate when answering a question.
|
||||
|
||||
Mutation:
|
||||
```
|
||||
mutation CreateAnswer($position: Int!, $questionId: Int!, $personId: Int!) {
|
||||
createAnswer(input: {answer: {position: $position, questionId: $questionId, personId: $personId}}) {
|
||||
answer {
|
||||
position
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
Variables
|
||||
```
|
||||
{
|
||||
"questionId": 1,
|
||||
"personId": 2,
|
||||
"position": 2
|
||||
}
|
||||
```
|
||||
Also change the `personId` to see that the candidate can only answer for themself.
|
||||
|
||||
|
||||
##### Updating, Deleting
|
||||
|
||||
Works the same as creating and has the same restrictions for the specific roles.
|
||||
The exact mutations can be inferred looking at the schema definitions.
|
||||
|
|
Loading…
Reference in a new issue