Lots of code refactors
This commit is contained in:
parent
4f82c80922
commit
01676c59e4
3
.env.example
Normal file
3
.env.example
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
SENDGRID_API_KEY=
|
||||||
|
JWT_SECRET=
|
||||||
|
SITE_URL=test.com
|
21
LICENCE
Normal file
21
LICENCE
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2020 Ditriy Shishkov <me@dmitriy.com> (https://dmitriy.icu)
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
19
README.md
19
README.md
@ -1,10 +1,27 @@
|
|||||||
# QuestionForm Backend
|
# QuestionForm Backend
|
||||||
|
|
||||||
Backend used with QuestionForm application.
|
Backend for QuestionForm application.
|
||||||
|
|
||||||
# Built with:
|
# Built with:
|
||||||
|
|
||||||
- Prisma
|
- Prisma
|
||||||
- Graphql
|
- Graphql
|
||||||
- Apollo Server
|
- Apollo Server
|
||||||
|
- Graphql code generator
|
||||||
- SendGrid
|
- SendGrid
|
||||||
|
|
||||||
|
# Setting up development environment
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ git clone https://github.com/Dm1tr1y147/questionForm_backend
|
||||||
|
$ yarn
|
||||||
|
$ mv .env.example .env && vim .env
|
||||||
|
$ mv prisma/.env.example prisma/.env && vim .env
|
||||||
|
$ prisma migrate save --experimental && prisma migrate up --experimental
|
||||||
|
$ prisma generate
|
||||||
|
$ yarn dev
|
||||||
|
```
|
||||||
|
|
||||||
|
# API
|
||||||
|
|
||||||
|
_...coming soon..._
|
||||||
|
1
prisma/.env.example
Normal file
1
prisma/.env.example
Normal file
@ -0,0 +1 @@
|
|||||||
|
DATABASE_URL="postgres://"
|
@ -4,13 +4,14 @@ import {
|
|||||||
AuthenticationError,
|
AuthenticationError,
|
||||||
ForbiddenError
|
ForbiddenError
|
||||||
} from 'apollo-server-express'
|
} from 'apollo-server-express'
|
||||||
import { CheckRightsAndResolve } from './types'
|
|
||||||
import { getDBFormAuthor } from '../db'
|
|
||||||
import { PrismaClient } from '@prisma/client'
|
import { PrismaClient } from '@prisma/client'
|
||||||
import { sendToken } from '../mailer'
|
|
||||||
|
|
||||||
require('dotenv').config()
|
require('dotenv').config()
|
||||||
|
|
||||||
|
import { CheckRightsAndResolve } from './types'
|
||||||
|
import { getDBFormAuthor } from '../db'
|
||||||
|
import { sendToken } from './mailer'
|
||||||
|
|
||||||
const checkRightsAndResolve: CheckRightsAndResolve = async (params) => {
|
const checkRightsAndResolve: CheckRightsAndResolve = async (params) => {
|
||||||
const { user, expected, controller } = params
|
const { user, expected, controller } = params
|
||||||
|
|
||||||
@ -26,7 +27,7 @@ const checkRightsAndResolve: CheckRightsAndResolve = async (params) => {
|
|||||||
const getFormAuthor = async (db: PrismaClient, id: number) => {
|
const getFormAuthor = async (db: PrismaClient, id: number) => {
|
||||||
const author = await getDBFormAuthor(db, id)
|
const author = await getDBFormAuthor(db, id)
|
||||||
|
|
||||||
if (!author) throw new ApolloError('Not found')
|
if (!author) throw new ApolloError('Not found', 'NOTFOUND')
|
||||||
|
|
||||||
const authorId = author.author.id
|
const authorId = author.author.id
|
||||||
|
|
||||||
@ -40,7 +41,7 @@ const tokenGenerate = (email: string, id: number) => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const sendTokenEmail = async (
|
const genAndSendToken = async (
|
||||||
email: string,
|
email: string,
|
||||||
user: { id: number; name: string }
|
user: { id: number; name: string }
|
||||||
) => {
|
) => {
|
||||||
@ -48,7 +49,8 @@ const sendTokenEmail = async (
|
|||||||
|
|
||||||
const res = await sendToken(user.name, email, token)
|
const res = await sendToken(user.name, email, token)
|
||||||
|
|
||||||
if (res[0].statusCode != 202) return new ApolloError("Couldn't send email")
|
if (res[0].statusCode != 202)
|
||||||
|
return new ApolloError("Couldn't send email", 'EMAILSENDERROR')
|
||||||
}
|
}
|
||||||
|
|
||||||
export { checkRightsAndResolve, getFormAuthor, sendTokenEmail, tokenGenerate }
|
export { checkRightsAndResolve, getFormAuthor, genAndSendToken }
|
||||||
|
@ -1,15 +1,21 @@
|
|||||||
import { Answer, PrismaClient } from '@prisma/client'
|
import { Answer as DbAnswer, PrismaClient } from '@prisma/client'
|
||||||
import { ApolloError } from 'apollo-server-express'
|
import { ApolloError, UserInputError } from 'apollo-server-express'
|
||||||
|
|
||||||
import {
|
import {
|
||||||
ChoisesQuestion,
|
Form,
|
||||||
Form as GraphqlForm,
|
Form as GraphqlForm,
|
||||||
FormSubmission,
|
|
||||||
InputQuestion,
|
InputQuestion,
|
||||||
MutationCreateFormArgs,
|
MutationCreateFormArgs,
|
||||||
MutationFormSubmitArgs,
|
MutationFormSubmitArgs,
|
||||||
Question
|
ServerAnswer
|
||||||
} from '../typeDefs/typeDefs.gen'
|
} from '../typeDefs/typeDefs.gen'
|
||||||
import { createChoises, newForm } from './types'
|
import {
|
||||||
|
CreateChoises,
|
||||||
|
FormConstructor,
|
||||||
|
UploadedChoisesQuestion,
|
||||||
|
UploadedInputQuestion,
|
||||||
|
UploadedQuestion
|
||||||
|
} from './types'
|
||||||
import {
|
import {
|
||||||
createDBForm,
|
createDBForm,
|
||||||
getDBForm,
|
getDBForm,
|
||||||
@ -21,103 +27,119 @@ const getForm = async (
|
|||||||
db: PrismaClient,
|
db: PrismaClient,
|
||||||
id: number,
|
id: number,
|
||||||
user: { requesterId: number; userId: number }
|
user: { requesterId: number; userId: number }
|
||||||
) => {
|
): Promise<Form> => {
|
||||||
|
try {
|
||||||
const dbForm = await getDBForm(db, id, user)
|
const dbForm = await getDBForm(db, id, user)
|
||||||
|
|
||||||
if (dbForm == null) throw new ApolloError('Not found')
|
if (!dbForm) throw new ApolloError('Not found', 'NOTFOUND')
|
||||||
|
|
||||||
const form: GraphqlForm = {
|
const form: GraphqlForm = {
|
||||||
author: dbForm.author,
|
author: dbForm.author,
|
||||||
dateCreated: dbForm.dateCreated.toString(),
|
dateCreated: dbForm.dateCreated.toString(),
|
||||||
id: dbForm.id,
|
id: dbForm.id,
|
||||||
questions: [...dbForm.choisesQuestions, ...dbForm.inputQuestions],
|
questions: [...dbForm.choisesQuestions, ...dbForm.inputQuestions],
|
||||||
submissions: user.requesterId
|
submissions: dbForm.submissions.map((submission) => ({
|
||||||
? dbForm.submissions.map((submission) => ({
|
|
||||||
answers: submission.answers,
|
answers: submission.answers,
|
||||||
date: submission.date.toString(),
|
date: submission.date.toString(),
|
||||||
id: submission.id
|
id: submission.id
|
||||||
}))
|
})),
|
||||||
: undefined,
|
|
||||||
title: dbForm.title
|
title: dbForm.title
|
||||||
}
|
}
|
||||||
|
|
||||||
return form
|
return form
|
||||||
|
} catch (err) {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const getForms = async (db: PrismaClient, userId: number) => {
|
const getForms = async (db: PrismaClient, userId: number): Promise<Form[]> => {
|
||||||
|
try {
|
||||||
const dbForms = await getDBFormsByUser(db, userId)
|
const dbForms = await getDBFormsByUser(db, userId)
|
||||||
|
|
||||||
const forms = [
|
if (!dbForms) throw new ApolloError("Couldn't load forms", 'FETCHINGERROR')
|
||||||
...dbForms.map((form) => ({
|
|
||||||
|
const forms: Form[] = dbForms.map((form) => ({
|
||||||
dateCreated: form.dateCreated.toString(),
|
dateCreated: form.dateCreated.toString(),
|
||||||
id: form.id,
|
id: form.id,
|
||||||
questions: [...form.choisesQuestions, ...form.inputQuestions],
|
questions: [...form.choisesQuestions, ...form.inputQuestions],
|
||||||
submissions: form.submissions.map<FormSubmission>((submission) => ({
|
submissions: form.submissions.map((submission) => ({
|
||||||
answers: submission.answers,
|
answers: submission.answers,
|
||||||
date: submission.date.toString(),
|
date: submission.date.toString(),
|
||||||
id: submission.id
|
id: submission.id
|
||||||
})),
|
})),
|
||||||
title: form.title
|
title: form.title
|
||||||
}))
|
}))
|
||||||
]
|
|
||||||
|
|
||||||
return forms
|
return forms
|
||||||
|
} catch (err) {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const createFormFrom = async (
|
const createFormFrom = async (
|
||||||
db: PrismaClient,
|
db: PrismaClient,
|
||||||
params: MutationCreateFormArgs,
|
params: MutationCreateFormArgs,
|
||||||
id: number
|
id: number
|
||||||
) => {
|
): Promise<ServerAnswer> => {
|
||||||
const parsedQuestions = <Question[]>JSON.parse(params.questions)
|
try {
|
||||||
const newForm: newForm = {
|
const parsedQuestions = <UploadedQuestion[]>JSON.parse(params.questions)
|
||||||
|
|
||||||
|
const newForm: FormConstructor = {
|
||||||
choisesQuestions: {
|
choisesQuestions: {
|
||||||
create: parsedQuestions.flatMap<createChoises>(
|
create: parsedQuestions.flatMap<CreateChoises>(
|
||||||
(val: InputQuestion | ChoisesQuestion, index) => {
|
(uQuestion: UploadedChoisesQuestion | UploadedInputQuestion, index) =>
|
||||||
if ('type' in val) {
|
'type' in uQuestion
|
||||||
return [
|
? [
|
||||||
{
|
{
|
||||||
number: index,
|
number: index,
|
||||||
title: val.title,
|
title: uQuestion.title,
|
||||||
type: val.type,
|
type: uQuestion.type,
|
||||||
variants: {
|
variants: {
|
||||||
create: val.variants
|
create: uQuestion.variants
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
: []
|
||||||
|
|
||||||
{
|
|
||||||
return []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
inputQuestions: {
|
inputQuestions: {
|
||||||
create: parsedQuestions.filter(
|
create: parsedQuestions.flatMap<InputQuestion>(
|
||||||
(val: InputQuestion | ChoisesQuestion, index) => {
|
(uQuestion: UploadedChoisesQuestion | UploadedInputQuestion, index) =>
|
||||||
if (!('type' in val))
|
!('type' in uQuestion)
|
||||||
return {
|
? [{ number: index, title: uQuestion.title }]
|
||||||
number: index,
|
: []
|
||||||
title: val.title
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
title: params.title
|
title: params.title
|
||||||
}
|
}
|
||||||
|
|
||||||
return createDBForm(db, newForm, id)
|
const res = await createDBForm(db, newForm, id)
|
||||||
|
|
||||||
|
if (!res)
|
||||||
|
throw new ApolloError("Couldn't create new form", 'FORMCREATIONERROR')
|
||||||
|
|
||||||
|
return { success: true }
|
||||||
|
} catch (err) {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const submitAnswer = async (
|
const submitAnswer = async (
|
||||||
db: PrismaClient,
|
db: PrismaClient,
|
||||||
{ answers, formId }: MutationFormSubmitArgs,
|
{ answers, formId }: MutationFormSubmitArgs,
|
||||||
userId: number
|
userId: number
|
||||||
) => {
|
): Promise<ServerAnswer> => {
|
||||||
const parsedAnswers = <Answer[]>JSON.parse(answers)
|
try {
|
||||||
|
const parsedAnswers = <DbAnswer[]>JSON.parse(answers)
|
||||||
|
|
||||||
return submitDBAnswer(db, userId, formId, parsedAnswers)
|
const res = await submitDBAnswer(db, userId, formId, parsedAnswers)
|
||||||
|
|
||||||
|
if (!res) throw new UserInputError("Can't submit form")
|
||||||
|
|
||||||
|
return { success: true }
|
||||||
|
} catch (err) {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export { createFormFrom, getForm, getForms, submitAnswer }
|
export { createFormFrom, getForm, getForms, submitAnswer }
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { checkRightsAndResolve, getFormAuthor, sendTokenEmail } from './auth'
|
import { checkRightsAndResolve, getFormAuthor, genAndSendToken } from './auth'
|
||||||
import { createFormFrom, getForm, getForms, submitAnswer } from './form'
|
import { createFormFrom, getForm, getForms, submitAnswer } from './form'
|
||||||
import { findUserBy } from './user'
|
import { findUserBy } from './user'
|
||||||
|
|
||||||
@ -6,9 +6,9 @@ export {
|
|||||||
checkRightsAndResolve,
|
checkRightsAndResolve,
|
||||||
createFormFrom,
|
createFormFrom,
|
||||||
findUserBy,
|
findUserBy,
|
||||||
|
genAndSendToken,
|
||||||
getForm,
|
getForm,
|
||||||
getFormAuthor,
|
getFormAuthor,
|
||||||
getForms,
|
getForms,
|
||||||
sendTokenEmail,
|
|
||||||
submitAnswer
|
submitAnswer
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@ import sgMail from '@sendgrid/mail'
|
|||||||
|
|
||||||
require('dotenv').config()
|
require('dotenv').config()
|
||||||
|
|
||||||
sgMail.setApiKey(process.env.SENDGRID_API_KEY!)
|
sgMail.setApiKey('' + process.env.SENDGRID_API_KEY)
|
||||||
|
|
||||||
const sendToken = (username: string, email: string, token: string) => {
|
const sendToken = (username: string, email: string, token: string) => {
|
||||||
return sgMail.send({
|
return sgMail.send({
|
@ -1,3 +1,4 @@
|
|||||||
|
import { ChoiseType } from '@prisma/client'
|
||||||
import {
|
import {
|
||||||
ChoisesQuestion,
|
ChoisesQuestion,
|
||||||
InputQuestion,
|
InputQuestion,
|
||||||
@ -5,14 +6,14 @@ import {
|
|||||||
} from '../typeDefs/typeDefs.gen'
|
} from '../typeDefs/typeDefs.gen'
|
||||||
import { JwtPayloadType } from '../types'
|
import { JwtPayloadType } from '../types'
|
||||||
|
|
||||||
type expectedType = {
|
type ExpectedType = {
|
||||||
id: number
|
id: number
|
||||||
self: boolean
|
self: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ICheckRightsAndResolve<T> {
|
interface ICheckRightsAndResolve<T> {
|
||||||
controller: T
|
controller: T
|
||||||
expected: expectedType
|
expected: ExpectedType
|
||||||
user: JwtPayloadType | null
|
user: JwtPayloadType | null
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -20,16 +21,32 @@ type CheckRightsAndResolve = <ReturnType, ControllerType extends Function>(
|
|||||||
params: ICheckRightsAndResolve<ControllerType>
|
params: ICheckRightsAndResolve<ControllerType>
|
||||||
) => Promise<ReturnType>
|
) => Promise<ReturnType>
|
||||||
|
|
||||||
type newForm = {
|
type FormConstructor = {
|
||||||
choisesQuestions: {
|
choisesQuestions: { create: CreateChoises[] }
|
||||||
create: createChoises[]
|
|
||||||
}
|
|
||||||
inputQuestions: { create: InputQuestion[] }
|
inputQuestions: { create: InputQuestion[] }
|
||||||
title: string
|
title: string
|
||||||
}
|
}
|
||||||
|
|
||||||
type createChoises = Omit<ChoisesQuestion, 'variants'> & {
|
type CreateChoises = Omit<ChoisesQuestion, 'variants'> & {
|
||||||
variants: { create: Variant[] }
|
variants: { create: Variant[] }
|
||||||
}
|
}
|
||||||
|
|
||||||
export { CheckRightsAndResolve, createChoises, newForm }
|
type UploadedQuestion = {
|
||||||
|
title: string
|
||||||
|
}
|
||||||
|
|
||||||
|
type UploadedChoisesQuestion = UploadedQuestion & {
|
||||||
|
type: ChoiseType
|
||||||
|
variants: Variant[]
|
||||||
|
}
|
||||||
|
|
||||||
|
type UploadedInputQuestion = UploadedQuestion
|
||||||
|
|
||||||
|
export {
|
||||||
|
CheckRightsAndResolve,
|
||||||
|
CreateChoises,
|
||||||
|
FormConstructor,
|
||||||
|
UploadedChoisesQuestion,
|
||||||
|
UploadedInputQuestion,
|
||||||
|
UploadedQuestion
|
||||||
|
}
|
||||||
|
@ -2,27 +2,43 @@ import { createDBUser, findDBUserBy } from '../db'
|
|||||||
import { IFindUserParams } from '../db/types'
|
import { IFindUserParams } from '../db/types'
|
||||||
import { MutationRegisterArgs, User } from '../typeDefs/typeDefs.gen'
|
import { MutationRegisterArgs, User } from '../typeDefs/typeDefs.gen'
|
||||||
import { PrismaClient } from '@prisma/client'
|
import { PrismaClient } from '@prisma/client'
|
||||||
import { UserInputError } from 'apollo-server-express'
|
import { ApolloError, UserInputError } from 'apollo-server-express'
|
||||||
|
|
||||||
const createUser = async (
|
const createUser = async (
|
||||||
db: PrismaClient,
|
db: PrismaClient,
|
||||||
{ email, name }: MutationRegisterArgs
|
{ email, name }: MutationRegisterArgs
|
||||||
): Promise<User> => {
|
): Promise<User> => {
|
||||||
|
try {
|
||||||
if (!email || !name)
|
if (!email || !name)
|
||||||
throw new UserInputError(
|
throw new UserInputError(
|
||||||
'Provide full user information',
|
'Provide full user information',
|
||||||
[!email ? [email] : [], !name ? [name] : []].flat()
|
[!email ? [email] : [], !name ? [name] : []].flat()
|
||||||
)
|
)
|
||||||
|
|
||||||
return await createDBUser(db, { email, name })
|
const newUser = await createDBUser(db, { email, name })
|
||||||
|
|
||||||
|
if (!newUser)
|
||||||
|
throw new ApolloError("Couldn't create user", 'USERCREATIONERROR')
|
||||||
|
|
||||||
|
return newUser
|
||||||
|
} catch (err) {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const findUserBy = async (db: PrismaClient, params: IFindUserParams) => {
|
const findUserBy = async (
|
||||||
|
db: PrismaClient,
|
||||||
|
params: IFindUserParams
|
||||||
|
): Promise<User> => {
|
||||||
|
try {
|
||||||
const user = await findDBUserBy(db, params)
|
const user = await findDBUserBy(db, params)
|
||||||
|
|
||||||
if (!user) throw new UserInputError('No such user')
|
if (!user) throw new UserInputError('No such user')
|
||||||
|
|
||||||
return user
|
return user
|
||||||
|
} catch (err) {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export { createUser, findUserBy }
|
export { createUser, findUserBy }
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
|
import { PrismaClient } from '@prisma/client'
|
||||||
|
|
||||||
import { Answer, MutationRegisterArgs } from '../typeDefs/typeDefs.gen'
|
import { Answer, MutationRegisterArgs } from '../typeDefs/typeDefs.gen'
|
||||||
import { IFindUserParams } from './types'
|
import { IFindUserParams } from './types'
|
||||||
import { newForm } from '../controllers/types'
|
import { FormConstructor } from '../controllers/types'
|
||||||
import { PrismaClient } from '@prisma/client'
|
|
||||||
import { UserInputError } from 'apollo-server-express'
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get form from DataBase
|
* Get form from DataBase
|
||||||
@ -14,15 +14,18 @@ import { UserInputError } from 'apollo-server-express'
|
|||||||
* @example
|
* @example
|
||||||
* const form = await getDBForm(db, id, true)
|
* const form = await getDBForm(db, id, true)
|
||||||
*/
|
*/
|
||||||
const getDBForm = async (
|
const getDBForm = (
|
||||||
db: PrismaClient,
|
db: PrismaClient,
|
||||||
formId: number,
|
formId: number,
|
||||||
user?: {
|
{
|
||||||
|
requesterId,
|
||||||
|
userId
|
||||||
|
}: {
|
||||||
requesterId: number
|
requesterId: number
|
||||||
userId: number
|
userId: number
|
||||||
}
|
}
|
||||||
) => {
|
) =>
|
||||||
return await db.form.findOne({
|
db.form.findOne({
|
||||||
include: {
|
include: {
|
||||||
author: {
|
author: {
|
||||||
select: {
|
select: {
|
||||||
@ -42,10 +45,10 @@ const getDBForm = async (
|
|||||||
answers: true
|
answers: true
|
||||||
},
|
},
|
||||||
where:
|
where:
|
||||||
user?.requesterId != user?.userId
|
requesterId != userId
|
||||||
? {
|
? {
|
||||||
user: {
|
user: {
|
||||||
id: user?.requesterId
|
id: requesterId
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
: undefined
|
: undefined
|
||||||
@ -55,7 +58,6 @@ const getDBForm = async (
|
|||||||
id: formId
|
id: formId
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get all forms of user
|
* Get all forms of user
|
||||||
@ -64,8 +66,8 @@ const getDBForm = async (
|
|||||||
* @example
|
* @example
|
||||||
* const forms = await getDBFormsByUser(db, userId)
|
* const forms = await getDBFormsByUser(db, userId)
|
||||||
*/
|
*/
|
||||||
const getDBFormsByUser = async (db: PrismaClient, id: number) => {
|
const getDBFormsByUser = (db: PrismaClient, id: number) =>
|
||||||
return await db.form.findMany({
|
db.form.findMany({
|
||||||
include: {
|
include: {
|
||||||
choisesQuestions: {
|
choisesQuestions: {
|
||||||
include: {
|
include: {
|
||||||
@ -85,10 +87,9 @@ const getDBFormsByUser = async (db: PrismaClient, id: number) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
|
||||||
|
|
||||||
const getDBFormAuthor = async (db: PrismaClient, id: number) => {
|
const getDBFormAuthor = (db: PrismaClient, id: number) =>
|
||||||
return await db.form.findOne({
|
db.form.findOne({
|
||||||
select: {
|
select: {
|
||||||
author: {
|
author: {
|
||||||
select: {
|
select: {
|
||||||
@ -100,52 +101,39 @@ const getDBFormAuthor = async (db: PrismaClient, id: number) => {
|
|||||||
id
|
id
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
|
||||||
|
|
||||||
const createDBUser = async (
|
const createDBUser = (
|
||||||
db: PrismaClient,
|
db: PrismaClient,
|
||||||
{ email, name }: MutationRegisterArgs
|
{ email, name }: MutationRegisterArgs
|
||||||
) => {
|
) =>
|
||||||
return await db.user.create({
|
db.user.create({
|
||||||
data: { email, name }
|
data: { email, name }
|
||||||
})
|
})
|
||||||
}
|
|
||||||
|
|
||||||
const findDBUserBy = async (db: PrismaClient, params: IFindUserParams) => {
|
const findDBUserBy = (db: PrismaClient, params: IFindUserParams) =>
|
||||||
const user = await db.user.findOne({
|
db.user.findOne({
|
||||||
where: {
|
where: {
|
||||||
...params
|
...params
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
if (!user) throw new UserInputError('Not found')
|
|
||||||
|
|
||||||
return user
|
const createDBForm = (db: PrismaClient, form: FormConstructor, id: number) =>
|
||||||
}
|
db.form.create({
|
||||||
|
|
||||||
const createDBForm = async (
|
|
||||||
db: PrismaClient,
|
|
||||||
{ title, inputQuestions, choisesQuestions }: newForm,
|
|
||||||
id: number
|
|
||||||
) => {
|
|
||||||
return await db.form.create({
|
|
||||||
data: {
|
data: {
|
||||||
author: {
|
author: {
|
||||||
connect: { id }
|
connect: { id }
|
||||||
},
|
},
|
||||||
choisesQuestions,
|
...form
|
||||||
inputQuestions,
|
|
||||||
title
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
|
||||||
|
|
||||||
const submitDBAnswer = async (
|
const submitDBAnswer = (
|
||||||
db: PrismaClient,
|
db: PrismaClient,
|
||||||
userId: number,
|
userId: number,
|
||||||
formId: number,
|
formId: number,
|
||||||
formAnswers: Answer[]
|
formAnswers: Answer[]
|
||||||
) => {
|
) =>
|
||||||
const res = await db.formSubmission.create({
|
db.formSubmission.create({
|
||||||
data: {
|
data: {
|
||||||
answers: {
|
answers: {
|
||||||
create: formAnswers
|
create: formAnswers
|
||||||
@ -163,11 +151,6 @@ const submitDBAnswer = async (
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
if (!res) throw new UserInputError("Can't submit form")
|
|
||||||
|
|
||||||
return { success: true }
|
|
||||||
}
|
|
||||||
|
|
||||||
export {
|
export {
|
||||||
createDBForm,
|
createDBForm,
|
||||||
createDBUser,
|
createDBUser,
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { getDBForm } from '../db'
|
|
||||||
import { PromiseReturnType } from '@prisma/client'
|
import { PromiseReturnType } from '@prisma/client'
|
||||||
|
|
||||||
|
import { getDBForm } from '../db'
|
||||||
|
|
||||||
type FullForm = PromiseReturnType<typeof getDBForm>
|
type FullForm = PromiseReturnType<typeof getDBForm>
|
||||||
|
|
||||||
interface IFindUserParams {
|
interface IFindUserParams {
|
||||||
|
@ -66,8 +66,8 @@ const formsQuery: Resolver<Form[], {}, ApolloContextType> = async (
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const createForm: Resolver<
|
const createFormMutation: Resolver<
|
||||||
Form,
|
ServerAnswer,
|
||||||
{},
|
{},
|
||||||
ApolloContextType,
|
ApolloContextType,
|
||||||
MutationCreateFormArgs
|
MutationCreateFormArgs
|
||||||
@ -84,7 +84,7 @@ const createForm: Resolver<
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const formSubmit: Resolver<
|
const formSubmitMutation: Resolver<
|
||||||
ServerAnswer,
|
ServerAnswer,
|
||||||
{},
|
{},
|
||||||
ApolloContextType,
|
ApolloContextType,
|
||||||
@ -122,9 +122,9 @@ const AnswerResolver: AnswerResolvers = {
|
|||||||
|
|
||||||
export {
|
export {
|
||||||
AnswerResolver,
|
AnswerResolver,
|
||||||
createForm,
|
createFormMutation,
|
||||||
formQuery,
|
formQuery,
|
||||||
formsQuery,
|
formsQuery,
|
||||||
formSubmit,
|
formSubmitMutation,
|
||||||
QuestionResolver
|
QuestionResolver
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import {
|
import {
|
||||||
checkRightsAndResolve,
|
checkRightsAndResolve,
|
||||||
findUserBy,
|
findUserBy,
|
||||||
sendTokenEmail
|
genAndSendToken
|
||||||
} from '../controllers'
|
} from '../controllers'
|
||||||
import { createUser } from '../controllers/user'
|
import { createUser } from '../controllers/user'
|
||||||
import {
|
import {
|
||||||
@ -14,7 +14,7 @@ import {
|
|||||||
} from '../typeDefs/typeDefs.gen'
|
} from '../typeDefs/typeDefs.gen'
|
||||||
import { ApolloContextType } from '../types'
|
import { ApolloContextType } from '../types'
|
||||||
|
|
||||||
const loginResolver: Resolver<
|
const loginMutation: Resolver<
|
||||||
ServerAnswer,
|
ServerAnswer,
|
||||||
{},
|
{},
|
||||||
ApolloContextType,
|
ApolloContextType,
|
||||||
@ -23,7 +23,7 @@ const loginResolver: Resolver<
|
|||||||
try {
|
try {
|
||||||
const user = await findUserBy(db, { email })
|
const user = await findUserBy(db, { email })
|
||||||
|
|
||||||
await sendTokenEmail(email, user)
|
await genAndSendToken(email, user)
|
||||||
|
|
||||||
return { success: true }
|
return { success: true }
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@ -31,7 +31,7 @@ const loginResolver: Resolver<
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const registerResolver: Resolver<
|
const registerMutation: Resolver<
|
||||||
ServerAnswer,
|
ServerAnswer,
|
||||||
{},
|
{},
|
||||||
ApolloContextType,
|
ApolloContextType,
|
||||||
@ -40,7 +40,7 @@ const registerResolver: Resolver<
|
|||||||
try {
|
try {
|
||||||
const user = await createUser(db, { email, name })
|
const user = await createUser(db, { email, name })
|
||||||
|
|
||||||
await sendTokenEmail(email, user)
|
await genAndSendToken(email, user)
|
||||||
|
|
||||||
return { success: true }
|
return { success: true }
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@ -48,15 +48,14 @@ const registerResolver: Resolver<
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const userResolver: Resolver<
|
const userQuery: Resolver<User, {}, ApolloContextType, QueryUserArgs> = async (
|
||||||
User,
|
_,
|
||||||
{},
|
{ id },
|
||||||
ApolloContextType,
|
{ db, user }
|
||||||
QueryUserArgs
|
) => {
|
||||||
> = async (_, { id }, { db, user }) => {
|
try {
|
||||||
const findUserById = (id: number) => findUserBy(db, { id })
|
const findUserById = (id: number) => findUserBy(db, { id })
|
||||||
|
|
||||||
try {
|
|
||||||
return await checkRightsAndResolve({
|
return await checkRightsAndResolve({
|
||||||
controller: findUserById,
|
controller: findUserById,
|
||||||
expected: {
|
expected: {
|
||||||
@ -70,4 +69,4 @@ const userResolver: Resolver<
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export { loginResolver, registerResolver, userResolver }
|
export { loginMutation, registerMutation, userQuery }
|
||||||
|
@ -1,20 +1,19 @@
|
|||||||
import { ApolloContextType } from '../types'
|
|
||||||
import { Resolvers } from '../typeDefs/typeDefs.gen'
|
import { Resolvers } from '../typeDefs/typeDefs.gen'
|
||||||
import {
|
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,
|
createFormMutation as createForm,
|
||||||
formSubmit
|
formSubmitMutation as formSubmit
|
||||||
} from './Form'
|
} from './Form'
|
||||||
import {
|
import {
|
||||||
loginResolver as login,
|
loginMutation as login,
|
||||||
registerResolver as register,
|
registerMutation as register,
|
||||||
userResolver as user
|
userQuery as user
|
||||||
} from './User'
|
} from './User'
|
||||||
|
|
||||||
const resolvers: Resolvers<ApolloContextType> = {
|
const resolvers: Resolvers = {
|
||||||
Query: {
|
Query: {
|
||||||
form,
|
form,
|
||||||
forms,
|
forms,
|
||||||
|
@ -5,7 +5,7 @@ type Query {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Mutation {
|
type Mutation {
|
||||||
createForm(title: String!, questions: String!): Form!
|
createForm(title: String!, questions: String!): serverAnswer
|
||||||
formSubmit(formId: Int!, answers: String!): serverAnswer
|
formSubmit(formId: Int!, answers: String!): serverAnswer
|
||||||
login(email: String!): serverAnswer
|
login(email: String!): serverAnswer
|
||||||
register(name: String!, email: String!): serverAnswer
|
register(name: String!, email: String!): serverAnswer
|
||||||
|
Loading…
x
Reference in New Issue
Block a user