Added form submission mutation, some code refactoring

This commit is contained in:
Dmitriy Shishkov 2020-10-10 12:07:34 +05:00
parent 9439730f4c
commit a07e0d752f
9 changed files with 128 additions and 40 deletions

View File

@ -1,7 +1,7 @@
import { PrismaClient } from '@prisma/client' import { PrismaClient, Answer } from '@prisma/client'
import { ApolloError } from 'apollo-server-express' import { ApolloError } from 'apollo-server-express'
import { createDBForm, getDBForm, getDBFormByUser } from '../db' import { createDBForm, getDBForm, getDBFormByUser, submitDBAnswer } from '../db'
import { FullForm } from '../db/types' import { FullForm } from '../db/types'
import { import {
ChoisesQuestion, ChoisesQuestion,
@ -9,6 +9,7 @@ import {
FormSubmission, FormSubmission,
InputQuestion, InputQuestion,
MutationCreateFormArgs, MutationCreateFormArgs,
MutationFormSubmitArgs,
Question Question
} from '../typeDefs/typeDefs.gen' } from '../typeDefs/typeDefs.gen'
@ -98,4 +99,14 @@ const createFormFrom = async (
return createDBForm(db, newForm, id) return createDBForm(db, newForm, id)
} }
export { getForm, getForms, createFormFrom } const submitAnswer = async (
db: PrismaClient,
{ answers, formId }: MutationFormSubmitArgs,
userId: number
) => {
const parsedAnswers = <Answer[]>JSON.parse(answers)
return submitDBAnswer(db, userId, formId, parsedAnswers)
}
export { getForm, getForms, createFormFrom, submitAnswer }

View File

@ -1,5 +1,6 @@
import { getForm, getForms, createFormFrom } from './form' import { getForm, getForms, createFormFrom } from './form'
import { checkRightsAndResolve, getFormAuthor, sendTokenEmail } from './auth' import { checkRightsAndResolve, getFormAuthor, sendTokenEmail } from './auth'
import { findUserBy } from './user'
export { export {
checkRightsAndResolve, checkRightsAndResolve,
@ -7,5 +8,6 @@ export {
getFormAuthor, getFormAuthor,
getForms, getForms,
createFormFrom, createFormFrom,
sendTokenEmail sendTokenEmail,
findUserBy
} }

View File

@ -1,5 +1,8 @@
import { AnswerType } from '@prisma/client'
import { import {
Answer,
ChoisesQuestion, ChoisesQuestion,
FormSubmission,
InputQuestion, InputQuestion,
Variant Variant
} from '../typeDefs/typeDefs.gen' } from '../typeDefs/typeDefs.gen'

29
src/controllers/user.ts Normal file
View File

@ -0,0 +1,29 @@
import { PrismaClient } from '@prisma/client'
import { UserInputError } from 'apollo-server-express'
import { createDBUser, findDBUserBy } from '../db'
import { IFindUserParams } from '../db/types'
import { MutationRegisterArgs, User } from '../typeDefs/typeDefs.gen'
const createUser = async (
db: PrismaClient,
{ email, name }: MutationRegisterArgs
): Promise<User> => {
if (!email || !name)
throw new UserInputError(
'Provide full user information',
[!email ? [email] : [], !name ? [name] : []].flat()
)
return await createDBUser(db, { email, name })
}
const findUserBy = async (db: PrismaClient, params: IFindUserParams) => {
const user = await findDBUserBy(db, params)
if (!user) throw new UserInputError('No such user')
return user
}
export { createUser, findUserBy }

View File

@ -1,7 +1,7 @@
import { PrismaClient } from '@prisma/client' import { PrismaClient } from '@prisma/client'
import { UserInputError } from 'apollo-server-express' import { UserInputError } from 'apollo-server-express'
import { newForm } from '../controllers/types' import { newForm } from '../controllers/types'
import { MutationRegisterArgs } from '../typeDefs/typeDefs.gen' import { Answer, MutationRegisterArgs } from '../typeDefs/typeDefs.gen'
import { IFindUserParams } from './types' import { IFindUserParams } from './types'
const getDBForm = async (db: PrismaClient, id: number) => { const getDBForm = async (db: PrismaClient, id: number) => {
@ -95,8 +95,6 @@ const createDBForm = async (
{ title, inputQuestions, choisesQuestions }: newForm, { title, inputQuestions, choisesQuestions }: newForm,
id: number id: number
) => { ) => {
console.log(title, inputQuestions, choisesQuestions)
return await db.form.create({ return await db.form.create({
data: { data: {
author: { connect: { id } }, author: { connect: { id } },
@ -107,11 +105,39 @@ const createDBForm = async (
}) })
} }
const submitDBAnswer = async (
db: PrismaClient,
userId: number,
formId: number,
formAnswers: Answer[]
) => {
const res = await db.formSubmission.create({
data: {
user: {
connect: {
id: userId
}
},
Form: {
connect: {
id: formId
}
},
answers: { create: formAnswers }
}
})
if (!res) throw new UserInputError("Can't submit form")
return { success: true }
}
export { export {
getDBForm, getDBForm,
getDBFormByUser, getDBFormByUser,
getDBFormAuthor, getDBFormAuthor,
createDBUser, createDBUser,
findDBUserBy, findDBUserBy,
createDBForm createDBForm,
submitDBAnswer
} }

View File

@ -5,13 +5,16 @@ import {
getForms, getForms,
createFormFrom createFormFrom
} from '../controllers' } from '../controllers'
import { submitAnswer } from '../controllers/form'
import { import {
Form, Form,
QueryFormArgs, QueryFormArgs,
QuestionResolvers, QuestionResolvers,
Resolver, Resolver,
AnswerResolvers, AnswerResolvers,
MutationCreateFormArgs MutationCreateFormArgs,
ServerAnswer,
MutationFormSubmitArgs
} from '../typeDefs/typeDefs.gen' } from '../typeDefs/typeDefs.gen'
import { ApolloContextType } from '../types' import { ApolloContextType } from '../types'
@ -67,16 +70,8 @@ const createForm: Resolver<
{}, {},
ApolloContextType, ApolloContextType,
MutationCreateFormArgs MutationCreateFormArgs
> = async (_, { questions, title }, { db, user }) => { > = async (_, params, { db, user }) => {
const createNewForm = (id: number) => const createNewForm = (id: number) => createFormFrom(db, params, id)
createFormFrom(
db,
{
title,
questions
},
id
)
return await checkRightsAndResolve({ return await checkRightsAndResolve({
user, user,
@ -85,6 +80,21 @@ const createForm: Resolver<
}) })
} }
const formSubmit: Resolver<
ServerAnswer,
{},
ApolloContextType,
MutationFormSubmitArgs
> = async (_, params, { db, user }) => {
const submitNewAnswer = (userId: number) => submitAnswer(db, params, userId)
return await checkRightsAndResolve({
user,
expected: { id: 0, self: true },
controller: submitNewAnswer
})
}
const QuestionResolver: QuestionResolvers = { const QuestionResolver: QuestionResolvers = {
__resolveType(obj: any) { __resolveType(obj: any) {
if (obj.type) { if (obj.type) {
@ -103,4 +113,11 @@ const AnswerResolver: AnswerResolvers = {
} }
} }
export { formQuery, formsQuery, QuestionResolver, AnswerResolver, createForm } export {
formQuery,
formsQuery,
QuestionResolver,
AnswerResolver,
createForm,
formSubmit
}

View File

@ -1,27 +1,27 @@
import { UserInputError } from 'apollo-server-express' import {
checkRightsAndResolve,
import { checkRightsAndResolve, sendTokenEmail } from '../controllers' findUserBy,
import { createDBUser, findDBUserBy } from '../db' sendTokenEmail
} from '../controllers'
import { createUser } from '../controllers/user'
import { import {
MutationLoginArgs, MutationLoginArgs,
MutationRegisterArgs, MutationRegisterArgs,
Resolver, Resolver,
LoginResult, ServerAnswer,
User, User,
QueryUserArgs QueryUserArgs
} from '../typeDefs/typeDefs.gen' } from '../typeDefs/typeDefs.gen'
import { ApolloContextType } from '../types' import { ApolloContextType } from '../types'
const loginResolver: Resolver< const loginResolver: Resolver<
LoginResult, ServerAnswer,
{}, {},
ApolloContextType, ApolloContextType,
MutationLoginArgs MutationLoginArgs
> = async (_, { email }, { db }) => { > = async (_, { email }, { db }) => {
try { try {
const user = await findDBUserBy(db, { email }) const user = await findUserBy(db, { email })
if (!user) throw new UserInputError('No such user')
await sendTokenEmail(email, user) await sendTokenEmail(email, user)
@ -32,13 +32,13 @@ const loginResolver: Resolver<
} }
const registerResolver: Resolver< const registerResolver: Resolver<
LoginResult, ServerAnswer,
{}, {},
ApolloContextType, ApolloContextType,
MutationRegisterArgs MutationRegisterArgs
> = async (_, { email, name }, { db }) => { > = async (_, { email, name }, { db }) => {
try { try {
const user = await createDBUser(db, { email, name }) const user = await createUser(db, { email, name })
await sendTokenEmail(email, user) await sendTokenEmail(email, user)
@ -54,7 +54,7 @@ const userResolver: Resolver<
ApolloContextType, ApolloContextType,
QueryUserArgs QueryUserArgs
> = async (_, { id }, { db, user }) => { > = async (_, { id }, { db, user }) => {
const findUserById = (id: number) => findDBUserBy(db, { id }) const findUserById = (id: number) => findUserBy(db, { id })
try { try {
return await checkRightsAndResolve({ return await checkRightsAndResolve({

View File

@ -5,7 +5,8 @@ import {
QuestionResolver as Question, QuestionResolver as Question,
AnswerResolver as Answer, AnswerResolver as Answer,
formsQuery as forms, formsQuery as forms,
createForm createForm,
formSubmit
} from './Form' } from './Form'
import { import {
loginResolver as login, loginResolver as login,
@ -22,7 +23,8 @@ const resolvers: Resolvers<ApolloContextType> = {
Mutation: { Mutation: {
login, login,
register, register,
createForm createForm,
formSubmit
}, },
Question, Question,
Answer Answer

View File

@ -5,9 +5,10 @@ type Query {
} }
type Mutation { type Mutation {
login(email: String!): LoginResult login(email: String!): serverAnswer
register(name: String!, email: String!): LoginResult register(name: String!, email: String!): serverAnswer
createForm(title: String!, questions: String!): Form! createForm(title: String!, questions: String!): Form!
formSubmit(formId: Int!, answers: String!): serverAnswer
} }
type Form { type Form {
@ -47,18 +48,15 @@ type FormSubmission {
} }
interface Answer { interface Answer {
id: Int!
type: AnswerType! type: AnswerType!
} }
type InputAnswer implements Answer { type InputAnswer implements Answer {
id: Int!
type: AnswerType! type: AnswerType!
userInput: String userInput: String
} }
type ChoiseAnswer implements Answer { type ChoiseAnswer implements Answer {
id: Int!
type: AnswerType! type: AnswerType!
userChoise: Int! userChoise: Int!
} }
@ -81,6 +79,6 @@ type User {
forms: [Form!] forms: [Form!]
} }
type LoginResult { type serverAnswer {
success: Boolean! success: Boolean!
} }