# Kandimat Backend The kandimat 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. ## Introduction ### 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 kandimat 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.