Added form creating mutation

This commit is contained in:
Dmitriy Shishkov 2020-10-10 03:17:30 +05:00
parent 301281b7fc
commit 9439730f4c
9 changed files with 164 additions and 41 deletions

View File

@ -1,17 +1,23 @@
import { PrismaClient } from "@prisma/client" import { PrismaClient } from '@prisma/client'
import { ApolloError } from "apollo-server-express" import { ApolloError } from 'apollo-server-express'
import { getDBForm, getDBFormByUser } from "../db" import { createDBForm, getDBForm, getDBFormByUser } from '../db'
import { FullForm } from "../db/types" import { FullForm } from '../db/types'
import { Form as GraphqlForm, FormSubmission } from "../typeDefs/typeDefs.gen" import {
ChoisesQuestion,
Form as GraphqlForm,
FormSubmission,
InputQuestion,
MutationCreateFormArgs,
Question
} from '../typeDefs/typeDefs.gen'
const getForm = async ( import { createChoises, newForm } from './types'
db: PrismaClient,
id: number const getForm = async (db: PrismaClient, id: number) => {
): Promise<GraphqlForm | null> => {
const dbForm: FullForm = await getDBForm(db, id) const dbForm: FullForm = await getDBForm(db, id)
if (dbForm == null) throw new ApolloError("Not found") if (dbForm == null) throw new ApolloError('Not found')
const form: GraphqlForm = { const form: GraphqlForm = {
id: dbForm.id, id: dbForm.id,
@ -21,18 +27,15 @@ const getForm = async (
submissions: dbForm.submissions.map<FormSubmission>((submission) => ({ submissions: dbForm.submissions.map<FormSubmission>((submission) => ({
answers: submission.answers, answers: submission.answers,
date: submission.date.toString(), date: submission.date.toString(),
id: submission.id, id: submission.id
})), })),
author: dbForm.author, author: dbForm.author
} }
return form return form
} }
const getForms = async ( const getForms = async (db: PrismaClient, userId: number) => {
db: PrismaClient,
userId: number
): Promise<GraphqlForm[]> => {
const dbForms = await getDBFormByUser(db, userId) const dbForms = await getDBFormByUser(db, userId)
const forms = [ const forms = [
@ -44,12 +47,55 @@ const getForms = async (
submissions: form.submissions.map<FormSubmission>((submission) => ({ submissions: form.submissions.map<FormSubmission>((submission) => ({
answers: submission.answers, answers: submission.answers,
date: submission.date.toString(), date: submission.date.toString(),
id: submission.id, id: submission.id
})), }))
})), }))
] ]
return forms return forms
} }
export { getForm, getForms } const createFormFrom = async (
db: PrismaClient,
params: MutationCreateFormArgs,
id: number
) => {
const parsedQuestions = <Question[]>JSON.parse(params.questions)
const newForm: newForm = {
title: params.title,
inputQuestions: {
create: parsedQuestions.filter(
(val: InputQuestion | ChoisesQuestion, index) => {
if (!('type' in val))
return {
number: index,
title: val.title
}
}
)
},
choisesQuestions: {
create: parsedQuestions.flatMap<createChoises>(
(val: InputQuestion | ChoisesQuestion, index) => {
if ('type' in val) {
return [
{
number: index,
title: val.title,
type: val.type,
variants: { create: val.variants }
}
]
}
{
return []
}
}
)
}
}
return createDBForm(db, newForm, id)
}
export { getForm, getForms, createFormFrom }

View File

@ -1,4 +1,11 @@
import { getForm, getForms } from "./form" import { getForm, getForms, createFormFrom } from './form'
import { checkRightsAndResolve, getFormAuthor } from "./auth" import { checkRightsAndResolve, getFormAuthor, sendTokenEmail } from './auth'
export { checkRightsAndResolve, getForm, getFormAuthor, getForms } export {
checkRightsAndResolve,
getForm,
getFormAuthor,
getForms,
createFormFrom,
sendTokenEmail
}

View File

@ -1,3 +1,8 @@
import {
ChoisesQuestion,
InputQuestion,
Variant
} from '../typeDefs/typeDefs.gen'
import { JwtPayloadType } from '../types' import { JwtPayloadType } from '../types'
type expectedType = { type expectedType = {
@ -15,4 +20,16 @@ type CheckRightsAndResolve = <ReturnType, ControllerType extends Function>(
params: ICheckRightsAndResolve<ControllerType> params: ICheckRightsAndResolve<ControllerType>
) => Promise<ReturnType> ) => Promise<ReturnType>
export { CheckRightsAndResolve } type newForm = {
title: string
choisesQuestions: {
create: createChoises[]
}
inputQuestions: { create: InputQuestion[] }
}
type createChoises = Omit<ChoisesQuestion, 'variants'> & {
variants: { create: Variant[] }
}
export { CheckRightsAndResolve, newForm, createChoises }

View File

@ -1,5 +1,6 @@
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 { MutationRegisterArgs } from '../typeDefs/typeDefs.gen' import { MutationRegisterArgs } from '../typeDefs/typeDefs.gen'
import { IFindUserParams } from './types' import { IFindUserParams } from './types'
@ -69,7 +70,7 @@ const getDBFormAuthor = async (db: PrismaClient, id: number) => {
}) })
} }
const createUser = async ( const createDBUser = async (
db: PrismaClient, db: PrismaClient,
{ email, name }: MutationRegisterArgs { email, name }: MutationRegisterArgs
) => { ) => {
@ -78,7 +79,7 @@ const createUser = async (
}) })
} }
const findUserBy = async (db: PrismaClient, params: IFindUserParams) => { const findDBUserBy = async (db: PrismaClient, params: IFindUserParams) => {
const user = await db.user.findOne({ const user = await db.user.findOne({
where: { where: {
...params ...params
@ -89,4 +90,28 @@ const findUserBy = async (db: PrismaClient, params: IFindUserParams) => {
return user return user
} }
export { getDBForm, getDBFormByUser, getDBFormAuthor, createUser, findUserBy } const createDBForm = async (
db: PrismaClient,
{ title, inputQuestions, choisesQuestions }: newForm,
id: number
) => {
console.log(title, inputQuestions, choisesQuestions)
return await db.form.create({
data: {
author: { connect: { id } },
title,
choisesQuestions,
inputQuestions
}
})
}
export {
getDBForm,
getDBFormByUser,
getDBFormAuthor,
createDBUser,
findDBUserBy,
createDBForm
}

View File

@ -2,14 +2,16 @@ import {
checkRightsAndResolve, checkRightsAndResolve,
getForm, getForm,
getFormAuthor, getFormAuthor,
getForms getForms,
createFormFrom
} from '../controllers' } from '../controllers'
import { import {
Form, Form,
QueryFormArgs, QueryFormArgs,
QuestionResolvers, QuestionResolvers,
Resolver, Resolver,
AnswerResolvers AnswerResolvers,
MutationCreateFormArgs
} from '../typeDefs/typeDefs.gen' } from '../typeDefs/typeDefs.gen'
import { ApolloContextType } from '../types' import { ApolloContextType } from '../types'
@ -60,6 +62,29 @@ const formsQuery: Resolver<Form[], {}, ApolloContextType> = async (
} }
} }
const createForm: Resolver<
Form,
{},
ApolloContextType,
MutationCreateFormArgs
> = async (_, { questions, title }, { db, user }) => {
const createNewForm = (id: number) =>
createFormFrom(
db,
{
title,
questions
},
id
)
return await checkRightsAndResolve({
user,
expected: { id: 0, self: true },
controller: createNewForm
})
}
const QuestionResolver: QuestionResolvers = { const QuestionResolver: QuestionResolvers = {
__resolveType(obj: any) { __resolveType(obj: any) {
if (obj.type) { if (obj.type) {
@ -78,4 +103,4 @@ const AnswerResolver: AnswerResolvers = {
} }
} }
export { formQuery, formsQuery, QuestionResolver, AnswerResolver } export { formQuery, formsQuery, QuestionResolver, AnswerResolver, createForm }

View File

@ -1,7 +1,7 @@
import { UserInputError } from 'apollo-server-express' import { UserInputError } from 'apollo-server-express'
import { checkRightsAndResolve, sendTokenEmail } from '../controllers/auth' import { checkRightsAndResolve, sendTokenEmail } from '../controllers'
import { createUser, findUserBy } from '../db' import { createDBUser, findDBUserBy } from '../db'
import { import {
MutationLoginArgs, MutationLoginArgs,
MutationRegisterArgs, MutationRegisterArgs,
@ -19,7 +19,7 @@ const loginResolver: Resolver<
MutationLoginArgs MutationLoginArgs
> = async (_, { email }, { db }) => { > = async (_, { email }, { db }) => {
try { try {
const user = await findUserBy(db, { email }) const user = await findDBUserBy(db, { email })
if (!user) throw new UserInputError('No such user') if (!user) throw new UserInputError('No such user')
@ -38,7 +38,7 @@ const registerResolver: Resolver<
MutationRegisterArgs MutationRegisterArgs
> = async (_, { email, name }, { db }) => { > = async (_, { email, name }, { db }) => {
try { try {
const user = await createUser(db, { email, name }) const user = await createDBUser(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) => findUserBy(db, { id }) const findUserById = (id: number) => findDBUserBy(db, { id })
try { try {
return await checkRightsAndResolve({ return await checkRightsAndResolve({

View File

@ -4,7 +4,8 @@ import {
formQuery as form, formQuery as form,
QuestionResolver as Question, QuestionResolver as Question,
AnswerResolver as Answer, AnswerResolver as Answer,
formsQuery as forms formsQuery as forms,
createForm
} from './Form' } from './Form'
import { import {
loginResolver as login, loginResolver as login,
@ -20,7 +21,8 @@ const resolvers: Resolvers<ApolloContextType> = {
}, },
Mutation: { Mutation: {
login, login,
register register,
createForm
}, },
Question, Question,
Answer Answer

View File

@ -1,8 +1,8 @@
import { gql } from "apollo-server-express" import { gql } from 'apollo-server-express'
import fs from "fs" import fs from 'fs'
const typeDefs = gql( const typeDefs = gql(
fs.readFileSync(__dirname.concat("/typeDefs.gql"), { encoding: "utf-8" }) fs.readFileSync(__dirname.concat('/typeDefs.gql'), { encoding: 'utf-8' })
) )
export default typeDefs export default typeDefs

View File

@ -7,6 +7,7 @@ type Query {
type Mutation { type Mutation {
login(email: String!): LoginResult login(email: String!): LoginResult
register(name: String!, email: String!): LoginResult register(name: String!, email: String!): LoginResult
createForm(title: String!, questions: String!): Form!
} }
type Form { type Form {
@ -25,7 +26,7 @@ interface Question {
type ChoisesQuestion implements Question { type ChoisesQuestion implements Question {
title: String! title: String!
variants: [Variant!] variants: [Variant!]!
type: ChoiseType! type: ChoiseType!
number: Int! number: Int!
} }