ability to load submission by id if token is present and cleanup structure
This commit is contained in:
parent
3840bb585c
commit
8e87ca5eed
@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
|||||||
- user confirmation tokens
|
- user confirmation tokens
|
||||||
- email verification
|
- email verification
|
||||||
- idx for fields and logic to have stable order
|
- idx for fields and logic to have stable order
|
||||||
|
- ability to load submission by id if token is present
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import { AuthJwtModel } from '../../dto/auth/auth.jwt.model'
|
|||||||
import { AuthService } from '../../service/auth/auth.service'
|
import { AuthService } from '../../service/auth/auth.service'
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class AuthLoginResolver {
|
export class AuthLoginMutation {
|
||||||
constructor(
|
constructor(
|
||||||
private readonly auth: AuthService
|
private readonly auth: AuthService
|
||||||
) {
|
) {
|
||||||
@ -8,7 +8,7 @@ import { SettingService } from '../../service/setting.service'
|
|||||||
import { UserCreateService } from '../../service/user/user.create.service'
|
import { UserCreateService } from '../../service/user/user.create.service'
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class AuthRegisterResolver {
|
export class AuthRegisterMutation {
|
||||||
constructor(
|
constructor(
|
||||||
private readonly createUser: UserCreateService,
|
private readonly createUser: UserCreateService,
|
||||||
private readonly settingService: SettingService,
|
private readonly settingService: SettingService,
|
||||||
@ -1,7 +1,7 @@
|
|||||||
import { AuthLoginResolver } from './auth.login.resolver'
|
import { AuthLoginMutation } from './auth.login.mutation'
|
||||||
import { AuthRegisterResolver } from './auth.register.resolver'
|
import { AuthRegisterMutation } from './auth.register.mutation'
|
||||||
|
|
||||||
export const authServices = [
|
export const authServices = [
|
||||||
AuthRegisterResolver,
|
AuthRegisterMutation,
|
||||||
AuthLoginResolver,
|
AuthLoginMutation,
|
||||||
]
|
]
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { Args, Context, Query, Resolver } from '@nestjs/graphql'
|
import { Injectable } from '@nestjs/common'
|
||||||
import { GraphQLInt } from 'graphql'
|
import { Args, Context, Int, Query } from '@nestjs/graphql'
|
||||||
import { Roles } from '../../decorator/roles.decorator'
|
import { Roles } from '../../decorator/roles.decorator'
|
||||||
import { User } from '../../decorator/user.decorator'
|
import { User } from '../../decorator/user.decorator'
|
||||||
import { FormModel } from '../../dto/form/form.model'
|
import { FormModel } from '../../dto/form/form.model'
|
||||||
@ -9,8 +9,8 @@ import { UserEntity } from '../../entity/user.entity'
|
|||||||
import { FormService } from '../../service/form/form.service'
|
import { FormService } from '../../service/form/form.service'
|
||||||
import { ContextCache } from '../context.cache'
|
import { ContextCache } from '../context.cache'
|
||||||
|
|
||||||
@Resolver(() => FormPagerModel)
|
@Injectable()
|
||||||
export class FormSearchResolver {
|
export class FormListQuery {
|
||||||
constructor(
|
constructor(
|
||||||
private readonly formService: FormService,
|
private readonly formService: FormService,
|
||||||
) {
|
) {
|
||||||
@ -20,8 +20,8 @@ export class FormSearchResolver {
|
|||||||
@Roles('user')
|
@Roles('user')
|
||||||
async listForms(
|
async listForms(
|
||||||
@User() user: UserEntity,
|
@User() user: UserEntity,
|
||||||
@Args('start', {type: () => GraphQLInt, defaultValue: 0, nullable: true}) start: number,
|
@Args('start', {type: () => Int, defaultValue: 0, nullable: true}) start: number,
|
||||||
@Args('limit', {type: () => GraphQLInt, defaultValue: 50, nullable: true}) limit: number,
|
@Args('limit', {type: () => Int, defaultValue: 50, nullable: true}) limit: number,
|
||||||
@Context('cache') cache: ContextCache,
|
@Context('cache') cache: ContextCache,
|
||||||
): Promise<FormPagerModel> {
|
): Promise<FormPagerModel> {
|
||||||
const [forms, total] = await this.formService.find(
|
const [forms, total] = await this.formService.find(
|
||||||
@ -1,4 +1,5 @@
|
|||||||
import { Args, Context, ID, Query, Resolver } from '@nestjs/graphql'
|
import { Injectable } from '@nestjs/common'
|
||||||
|
import { Args, Context, ID, Query } from '@nestjs/graphql'
|
||||||
import { User } from '../../decorator/user.decorator'
|
import { User } from '../../decorator/user.decorator'
|
||||||
import { FormModel } from '../../dto/form/form.model'
|
import { FormModel } from '../../dto/form/form.model'
|
||||||
import { FormEntity } from '../../entity/form.entity'
|
import { FormEntity } from '../../entity/form.entity'
|
||||||
@ -6,7 +7,7 @@ import { UserEntity } from '../../entity/user.entity'
|
|||||||
import { FormService } from '../../service/form/form.service'
|
import { FormService } from '../../service/form/form.service'
|
||||||
import { ContextCache } from '../context.cache'
|
import { ContextCache } from '../context.cache'
|
||||||
|
|
||||||
@Resolver(() => FormModel)
|
@Injectable()
|
||||||
export class FormQuery {
|
export class FormQuery {
|
||||||
constructor(
|
constructor(
|
||||||
private readonly formService: FormService,
|
private readonly formService: FormService,
|
||||||
|
|||||||
@ -20,19 +20,19 @@ export class FormResolver {
|
|||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ResolveField('fields', () => [FormFieldModel])
|
@ResolveField(() => [FormFieldModel])
|
||||||
async getFields(
|
async fields(
|
||||||
@User() user: UserEntity,
|
@User() user: UserEntity,
|
||||||
@Parent() parent: FormModel,
|
@Parent() parent: FormModel,
|
||||||
@Context('cache') cache: ContextCache,
|
@Context('cache') cache: ContextCache,
|
||||||
): Promise<FormFieldModel[]> {
|
): Promise<FormFieldModel[]> {
|
||||||
const form = await cache.get<FormEntity>(cache.getCacheKey(FormEntity.name, parent.id))
|
const form = await cache.get<FormEntity>(cache.getCacheKey(FormEntity.name, parent.id))
|
||||||
|
|
||||||
return form.fields?.map(field => new FormFieldModel(field)) || []
|
return form.fields?.map(field => new FormFieldModel(field)).sort((a,b) => a.idx - b.idx) || []
|
||||||
}
|
}
|
||||||
|
|
||||||
@ResolveField('hooks', () => [FormHookModel])
|
@ResolveField(() => [FormHookModel])
|
||||||
async getHooks(
|
async hooks(
|
||||||
@User() user: UserEntity,
|
@User() user: UserEntity,
|
||||||
@Parent() parent: FormModel,
|
@Parent() parent: FormModel,
|
||||||
@Context('cache') cache: ContextCache,
|
@Context('cache') cache: ContextCache,
|
||||||
@ -42,9 +42,9 @@ export class FormResolver {
|
|||||||
return form.hooks?.map(hook => new FormHookModel(hook)) || []
|
return form.hooks?.map(hook => new FormHookModel(hook)) || []
|
||||||
}
|
}
|
||||||
|
|
||||||
@ResolveField('isLive', () => Boolean)
|
@ResolveField(() => Boolean)
|
||||||
@Roles('admin')
|
@Roles('admin')
|
||||||
async getRoles(
|
async isLive(
|
||||||
@User() user: UserEntity,
|
@User() user: UserEntity,
|
||||||
@Parent() parent: FormModel,
|
@Parent() parent: FormModel,
|
||||||
@Context('cache') cache: ContextCache,
|
@Context('cache') cache: ContextCache,
|
||||||
@ -58,9 +58,9 @@ export class FormResolver {
|
|||||||
return form.isLive
|
return form.isLive
|
||||||
}
|
}
|
||||||
|
|
||||||
@ResolveField('notifications', () => [FormNotificationModel])
|
@ResolveField(() => [FormNotificationModel])
|
||||||
@Roles('admin')
|
@Roles('admin')
|
||||||
async getNotifications(
|
async notifications(
|
||||||
@User() user: UserEntity,
|
@User() user: UserEntity,
|
||||||
@Parent() parent: FormModel,
|
@Parent() parent: FormModel,
|
||||||
@Context('cache') cache: ContextCache,
|
@Context('cache') cache: ContextCache,
|
||||||
@ -74,8 +74,8 @@ export class FormResolver {
|
|||||||
return form.notifications?.map(notification => new FormNotificationModel(notification)) || []
|
return form.notifications?.map(notification => new FormNotificationModel(notification)) || []
|
||||||
}
|
}
|
||||||
|
|
||||||
@ResolveField('design', () => DesignModel)
|
@ResolveField(() => DesignModel)
|
||||||
async getDesign(
|
async design(
|
||||||
@User() user: UserEntity,
|
@User() user: UserEntity,
|
||||||
@Parent() parent: FormModel,
|
@Parent() parent: FormModel,
|
||||||
@Context('cache') cache: ContextCache,
|
@Context('cache') cache: ContextCache,
|
||||||
@ -85,8 +85,8 @@ export class FormResolver {
|
|||||||
return new DesignModel(form.design)
|
return new DesignModel(form.design)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ResolveField('startPage', () => PageModel)
|
@ResolveField(() => PageModel)
|
||||||
async getStartPage(
|
async startPage(
|
||||||
@Parent() parent: FormModel,
|
@Parent() parent: FormModel,
|
||||||
@Context('cache') cache: ContextCache,
|
@Context('cache') cache: ContextCache,
|
||||||
): Promise<PageModel> {
|
): Promise<PageModel> {
|
||||||
@ -95,8 +95,8 @@ export class FormResolver {
|
|||||||
return new PageModel(form.startPage)
|
return new PageModel(form.startPage)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ResolveField('endPage', () => PageModel)
|
@ResolveField(() => PageModel)
|
||||||
async getEndPage(
|
async endPage(
|
||||||
@Parent() parent: FormModel,
|
@Parent() parent: FormModel,
|
||||||
@Context('cache') cache: ContextCache,
|
@Context('cache') cache: ContextCache,
|
||||||
): Promise<PageModel> {
|
): Promise<PageModel> {
|
||||||
@ -105,9 +105,9 @@ export class FormResolver {
|
|||||||
return new PageModel(form.endPage)
|
return new PageModel(form.endPage)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ResolveField('admin', () => UserModel, { nullable: true })
|
@ResolveField(() => UserModel, { nullable: true })
|
||||||
@Roles('admin')
|
@Roles('admin')
|
||||||
async getAdmin(
|
async admin(
|
||||||
@Parent() parent: FormModel,
|
@Parent() parent: FormModel,
|
||||||
@Context('cache') cache: ContextCache,
|
@Context('cache') cache: ContextCache,
|
||||||
): Promise<UserModel> {
|
): Promise<UserModel> {
|
||||||
|
|||||||
11
src/resolver/form/form.statistic.query.ts
Normal file
11
src/resolver/form/form.statistic.query.ts
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import { Injectable } from '@nestjs/common'
|
||||||
|
import { Query } from '@nestjs/graphql'
|
||||||
|
import { FormStatisticModel } from '../../dto/form/form.statistic.model'
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class FormStatisticQuery {
|
||||||
|
@Query(() => FormStatisticModel)
|
||||||
|
getFormStatistic(): FormStatisticModel {
|
||||||
|
return new FormStatisticModel()
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,5 +1,4 @@
|
|||||||
import { Query, ResolveField, Resolver } from '@nestjs/graphql'
|
import { Int, ResolveField, Resolver } from '@nestjs/graphql'
|
||||||
import { GraphQLInt } from 'graphql'
|
|
||||||
import { Roles } from '../../decorator/roles.decorator'
|
import { Roles } from '../../decorator/roles.decorator'
|
||||||
import { FormStatisticModel } from '../../dto/form/form.statistic.model'
|
import { FormStatisticModel } from '../../dto/form/form.statistic.model'
|
||||||
import { FormStatisticService } from '../../service/form/form.statistic.service'
|
import { FormStatisticService } from '../../service/form/form.statistic.service'
|
||||||
@ -11,14 +10,9 @@ export class FormStatisticResolver {
|
|||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Query(() => FormStatisticModel)
|
@ResolveField(() => Int)
|
||||||
getFormStatistic(): FormStatisticModel {
|
|
||||||
return new FormStatisticModel()
|
|
||||||
}
|
|
||||||
|
|
||||||
@ResolveField('total', () => GraphQLInt)
|
|
||||||
@Roles('admin')
|
@Roles('admin')
|
||||||
getTotal(): Promise<number> {
|
total(): Promise<number> {
|
||||||
return this.statisticService.getTotal()
|
return this.statisticService.getTotal()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,8 +1,9 @@
|
|||||||
import { FormCreateMutation } from './form.create.mutation'
|
import { FormCreateMutation } from './form.create.mutation'
|
||||||
import { FormDeleteMutation } from './form.delete.mutation'
|
import { FormDeleteMutation } from './form.delete.mutation'
|
||||||
|
import { FormListQuery } from './form.list.query'
|
||||||
import { FormQuery } from './form.query'
|
import { FormQuery } from './form.query'
|
||||||
import { FormResolver } from './form.resolver'
|
import { FormResolver } from './form.resolver'
|
||||||
import { FormSearchResolver } from './form.search.resolver'
|
import { FormStatisticQuery } from './form.statistic.query'
|
||||||
import { FormStatisticResolver } from './form.statistic.resolver'
|
import { FormStatisticResolver } from './form.statistic.resolver'
|
||||||
import { FormUpdateMutation } from './form.update.mutation'
|
import { FormUpdateMutation } from './form.update.mutation'
|
||||||
|
|
||||||
@ -11,7 +12,8 @@ export const formResolvers = [
|
|||||||
FormDeleteMutation,
|
FormDeleteMutation,
|
||||||
FormQuery,
|
FormQuery,
|
||||||
FormResolver,
|
FormResolver,
|
||||||
FormSearchResolver,
|
FormListQuery,
|
||||||
|
FormStatisticQuery,
|
||||||
FormStatisticResolver,
|
FormStatisticResolver,
|
||||||
FormUpdateMutation,
|
FormUpdateMutation,
|
||||||
]
|
]
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import { ProfileResolver } from './profile.resolver'
|
import { ProfileQuery } from './profile.query'
|
||||||
import { ProfileUpdateMutation } from './profile.update.mutation'
|
import { ProfileUpdateMutation } from './profile.update.mutation'
|
||||||
|
|
||||||
export const profileResolvers = [
|
export const profileResolvers = [
|
||||||
ProfileResolver,
|
ProfileQuery,
|
||||||
ProfileUpdateMutation,
|
ProfileUpdateMutation,
|
||||||
]
|
]
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
import { Injectable } from '@nestjs/common'
|
||||||
import { Context, Query } from '@nestjs/graphql'
|
import { Context, Query } from '@nestjs/graphql'
|
||||||
import { Roles } from '../../decorator/roles.decorator'
|
import { Roles } from '../../decorator/roles.decorator'
|
||||||
import { User } from '../../decorator/user.decorator'
|
import { User } from '../../decorator/user.decorator'
|
||||||
@ -5,7 +6,8 @@ import { ProfileModel } from '../../dto/profile/profile.model'
|
|||||||
import { UserEntity } from '../../entity/user.entity'
|
import { UserEntity } from '../../entity/user.entity'
|
||||||
import { ContextCache } from '../context.cache'
|
import { ContextCache } from '../context.cache'
|
||||||
|
|
||||||
export class ProfileResolver {
|
@Injectable()
|
||||||
|
export class ProfileQuery {
|
||||||
@Query(() => ProfileModel)
|
@Query(() => ProfileModel)
|
||||||
@Roles('user')
|
@Roles('user')
|
||||||
public me(
|
public me(
|
||||||
@ -1,7 +1,7 @@
|
|||||||
import { SettingMutation } from './setting.mutation'
|
import { SettingMutation } from './setting.mutation'
|
||||||
import { SettingResolver } from './setting.resolver'
|
import { SettingQuery } from './setting.query'
|
||||||
|
|
||||||
export const settingsResolvers = [
|
export const settingsResolvers = [
|
||||||
SettingResolver,
|
SettingQuery,
|
||||||
SettingMutation,
|
SettingMutation,
|
||||||
]
|
]
|
||||||
|
|||||||
@ -8,7 +8,7 @@ import { UserEntity } from '../../entity/user.entity'
|
|||||||
import { SettingService } from '../../service/setting.service'
|
import { SettingService } from '../../service/setting.service'
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class SettingResolver {
|
export class SettingQuery {
|
||||||
constructor(
|
constructor(
|
||||||
private readonly settingService: SettingService,
|
private readonly settingService: SettingService,
|
||||||
) {
|
) {
|
||||||
@ -1,17 +1,21 @@
|
|||||||
import { SubmissionFieldResolver } from './submission.field.resolver'
|
import { SubmissionFieldResolver } from './submission.field.resolver'
|
||||||
|
import { SubmissionListQuery } from './submission.list.query'
|
||||||
import { SubmissionProgressResolver } from './submission.progress.resolver'
|
import { SubmissionProgressResolver } from './submission.progress.resolver'
|
||||||
|
import { SubmissionQuery } from './submission.query'
|
||||||
import { SubmissionResolver } from './submission.resolver'
|
import { SubmissionResolver } from './submission.resolver'
|
||||||
import { SubmissionSearchResolver } from './submission.search.resolver'
|
|
||||||
import { SubmissionSetFieldMutation } from './submission.set.field.mutation'
|
import { SubmissionSetFieldMutation } from './submission.set.field.mutation'
|
||||||
import { SubmissionStartMutation } from './submission.start.mutation'
|
import { SubmissionStartMutation } from './submission.start.mutation'
|
||||||
|
import { SubmissionStatisticQuery } from './submission.statistic.query'
|
||||||
import { SubmissionStatisticResolver } from './submission.statistic.resolver'
|
import { SubmissionStatisticResolver } from './submission.statistic.resolver'
|
||||||
|
|
||||||
export const submissionResolvers = [
|
export const submissionResolvers = [
|
||||||
SubmissionFieldResolver,
|
SubmissionFieldResolver,
|
||||||
|
SubmissionListQuery,
|
||||||
SubmissionProgressResolver,
|
SubmissionProgressResolver,
|
||||||
|
SubmissionQuery,
|
||||||
SubmissionResolver,
|
SubmissionResolver,
|
||||||
SubmissionSearchResolver,
|
|
||||||
SubmissionSetFieldMutation,
|
SubmissionSetFieldMutation,
|
||||||
SubmissionStartMutation,
|
SubmissionStartMutation,
|
||||||
|
SubmissionStatisticQuery,
|
||||||
SubmissionStatisticResolver,
|
SubmissionStatisticResolver,
|
||||||
]
|
]
|
||||||
|
|||||||
@ -13,8 +13,8 @@ export class SubmissionFieldResolver {
|
|||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ResolveField('field', () => FormFieldModel, { nullable: true })
|
@ResolveField(() => FormFieldModel, { nullable: true })
|
||||||
async getFields(
|
async field(
|
||||||
@Parent() parent: SubmissionFieldModel,
|
@Parent() parent: SubmissionFieldModel,
|
||||||
@Context('cache') cache: ContextCache,
|
@Context('cache') cache: ContextCache,
|
||||||
): Promise<FormFieldModel> {
|
): Promise<FormFieldModel> {
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { Args, Context, ID, Query, Resolver } from '@nestjs/graphql'
|
import { Injectable } from '@nestjs/common'
|
||||||
import { GraphQLInt } from 'graphql'
|
import { Args, Context, ID, Int, Query } from '@nestjs/graphql'
|
||||||
import { User } from '../../decorator/user.decorator'
|
import { User } from '../../decorator/user.decorator'
|
||||||
import { SubmissionModel } from '../../dto/submission/submission.model'
|
import { SubmissionModel } from '../../dto/submission/submission.model'
|
||||||
import { SubmissionPagerModel } from '../../dto/submission/submission.pager.model'
|
import { SubmissionPagerModel } from '../../dto/submission/submission.pager.model'
|
||||||
@ -9,8 +9,8 @@ import { FormService } from '../../service/form/form.service'
|
|||||||
import { SubmissionService } from '../../service/submission/submission.service'
|
import { SubmissionService } from '../../service/submission/submission.service'
|
||||||
import { ContextCache } from '../context.cache'
|
import { ContextCache } from '../context.cache'
|
||||||
|
|
||||||
@Resolver(() => SubmissionPagerModel)
|
@Injectable()
|
||||||
export class SubmissionSearchResolver {
|
export class SubmissionListQuery {
|
||||||
constructor(
|
constructor(
|
||||||
private readonly formService: FormService,
|
private readonly formService: FormService,
|
||||||
private readonly submissionService: SubmissionService,
|
private readonly submissionService: SubmissionService,
|
||||||
@ -21,8 +21,8 @@ export class SubmissionSearchResolver {
|
|||||||
async listSubmissions(
|
async listSubmissions(
|
||||||
@User() user: UserEntity,
|
@User() user: UserEntity,
|
||||||
@Args('form', {type: () => ID}) id: string,
|
@Args('form', {type: () => ID}) id: string,
|
||||||
@Args('start', {type: () => GraphQLInt, defaultValue: 0, nullable: true}) start: number,
|
@Args('start', {type: () => Int, defaultValue: 0, nullable: true}) start: number,
|
||||||
@Args('limit', {type: () => GraphQLInt, defaultValue: 50, nullable: true}) limit: number,
|
@Args('limit', {type: () => Int, defaultValue: 50, nullable: true}) limit: number,
|
||||||
@Context('cache') cache: ContextCache,
|
@Context('cache') cache: ContextCache,
|
||||||
): Promise<SubmissionPagerModel> {
|
): Promise<SubmissionPagerModel> {
|
||||||
const form = await this.formService.findById(id)
|
const form = await this.formService.findById(id)
|
||||||
41
src/resolver/submission/submission.query.ts
Normal file
41
src/resolver/submission/submission.query.ts
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
import { Injectable } from '@nestjs/common'
|
||||||
|
import { Args, Context, ID, Query } from '@nestjs/graphql'
|
||||||
|
import { User } from '../../decorator/user.decorator'
|
||||||
|
import { SubmissionModel } from '../../dto/submission/submission.model'
|
||||||
|
import { SubmissionEntity } from '../../entity/submission.entity'
|
||||||
|
import { UserEntity } from '../../entity/user.entity'
|
||||||
|
import { FormService } from '../../service/form/form.service'
|
||||||
|
import { SubmissionService } from '../../service/submission/submission.service'
|
||||||
|
import { SubmissionTokenService } from '../../service/submission/submission.token.service'
|
||||||
|
import { ContextCache } from '../context.cache'
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class SubmissionQuery {
|
||||||
|
constructor(
|
||||||
|
private readonly formService: FormService,
|
||||||
|
private readonly submissionService: SubmissionService,
|
||||||
|
private readonly tokenService: SubmissionTokenService,
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Query(() => SubmissionModel)
|
||||||
|
async getSubmissionById(
|
||||||
|
@User() user: UserEntity,
|
||||||
|
@Args('id', {type: () => ID}) id: string,
|
||||||
|
@Args('token', {nullable: true}) token: string,
|
||||||
|
@Context('cache') cache: ContextCache,
|
||||||
|
): Promise<SubmissionModel> {
|
||||||
|
const submission = await this.submissionService.findById(id)
|
||||||
|
|
||||||
|
if (
|
||||||
|
!await this.tokenService.verify(token, submission.tokenHash)
|
||||||
|
&& !this.formService.isAdmin(submission.form, user)
|
||||||
|
) {
|
||||||
|
throw new Error('invalid form')
|
||||||
|
}
|
||||||
|
|
||||||
|
cache.add(cache.getCacheKey(SubmissionEntity.name, submission.id), submission)
|
||||||
|
|
||||||
|
return new SubmissionModel(submission)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -9,8 +9,8 @@ import { ContextCache } from '../context.cache'
|
|||||||
|
|
||||||
@Resolver(() => SubmissionModel)
|
@Resolver(() => SubmissionModel)
|
||||||
export class SubmissionResolver {
|
export class SubmissionResolver {
|
||||||
@ResolveField('fields', () => [SubmissionFieldModel])
|
@ResolveField(() => [SubmissionFieldModel])
|
||||||
async getFields(
|
async fields(
|
||||||
@User() user: UserEntity,
|
@User() user: UserEntity,
|
||||||
@Parent() parent: SubmissionModel,
|
@Parent() parent: SubmissionModel,
|
||||||
@Context('cache') cache: ContextCache,
|
@Context('cache') cache: ContextCache,
|
||||||
|
|||||||
11
src/resolver/submission/submission.statistic.query.ts
Normal file
11
src/resolver/submission/submission.statistic.query.ts
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import { Injectable } from '@nestjs/common'
|
||||||
|
import { Query } from '@nestjs/graphql'
|
||||||
|
import { SubmissionStatisticModel } from '../../dto/submission/submission.statistic.model'
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class SubmissionStatisticQuery {
|
||||||
|
@Query(() => SubmissionStatisticModel)
|
||||||
|
getSubmissionStatistic(): SubmissionStatisticModel {
|
||||||
|
return new SubmissionStatisticModel()
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,4 +1,4 @@
|
|||||||
import { Query, ResolveField, Resolver } from '@nestjs/graphql'
|
import { ResolveField, Resolver } from '@nestjs/graphql'
|
||||||
import { GraphQLInt } from 'graphql'
|
import { GraphQLInt } from 'graphql'
|
||||||
import { Roles } from '../../decorator/roles.decorator'
|
import { Roles } from '../../decorator/roles.decorator'
|
||||||
import { SubmissionStatisticModel } from '../../dto/submission/submission.statistic.model'
|
import { SubmissionStatisticModel } from '../../dto/submission/submission.statistic.model'
|
||||||
@ -11,15 +11,9 @@ export class SubmissionStatisticResolver {
|
|||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ResolveField(() => GraphQLInt)
|
||||||
@Query(() => SubmissionStatisticModel)
|
|
||||||
getSubmissionStatistic(): SubmissionStatisticModel {
|
|
||||||
return new SubmissionStatisticModel()
|
|
||||||
}
|
|
||||||
|
|
||||||
@ResolveField('total', () => GraphQLInt)
|
|
||||||
@Roles('admin')
|
@Roles('admin')
|
||||||
getTotal(): Promise<number> {
|
total(): Promise<number> {
|
||||||
return this.statisticService.getTotal()
|
return this.statisticService.getTotal()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,13 +1,17 @@
|
|||||||
import { UserDeleteMutation } from './user.delete.mutation'
|
import { UserDeleteMutation } from './user.delete.mutation'
|
||||||
|
import { UserListQuery } from './user.list.query'
|
||||||
|
import { UserQuery } from './user.query'
|
||||||
import { UserResolver } from './user.resolver'
|
import { UserResolver } from './user.resolver'
|
||||||
import { UserSearchResolver } from './user.search.resolver'
|
import { UserStatisticQuery } from './user.statistic.query'
|
||||||
import { UserStatisticResolver } from './user.statistic.resolver'
|
import { UserStatisticResolver } from './user.statistic.resolver'
|
||||||
import { UserUpdateMutation } from './user.update.mutation'
|
import { UserUpdateMutation } from './user.update.mutation'
|
||||||
|
|
||||||
export const userResolvers = [
|
export const userResolvers = [
|
||||||
UserDeleteMutation,
|
UserDeleteMutation,
|
||||||
|
UserListQuery,
|
||||||
|
UserQuery,
|
||||||
UserResolver,
|
UserResolver,
|
||||||
UserSearchResolver,
|
UserStatisticQuery,
|
||||||
UserStatisticResolver,
|
UserStatisticResolver,
|
||||||
UserUpdateMutation,
|
UserUpdateMutation,
|
||||||
]
|
]
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
import { Args, Context, Query, Resolver } from '@nestjs/graphql'
|
import { Args, Context, Int, Query, Resolver } from '@nestjs/graphql'
|
||||||
import { GraphQLInt } from 'graphql'
|
|
||||||
import { Roles } from '../../decorator/roles.decorator'
|
import { Roles } from '../../decorator/roles.decorator'
|
||||||
import { UserModel } from '../../dto/user/user.model'
|
import { UserModel } from '../../dto/user/user.model'
|
||||||
import { UserPagerModel } from '../../dto/user/user.pager.model'
|
import { UserPagerModel } from '../../dto/user/user.pager.model'
|
||||||
@ -8,7 +7,7 @@ import { UserService } from '../../service/user/user.service'
|
|||||||
import { ContextCache } from '../context.cache'
|
import { ContextCache } from '../context.cache'
|
||||||
|
|
||||||
@Resolver(() => UserPagerModel)
|
@Resolver(() => UserPagerModel)
|
||||||
export class UserSearchResolver {
|
export class UserListQuery {
|
||||||
constructor(
|
constructor(
|
||||||
private readonly userService: UserService,
|
private readonly userService: UserService,
|
||||||
) {
|
) {
|
||||||
@ -17,8 +16,8 @@ export class UserSearchResolver {
|
|||||||
@Query(() => UserPagerModel)
|
@Query(() => UserPagerModel)
|
||||||
@Roles('superuser')
|
@Roles('superuser')
|
||||||
async listUsers(
|
async listUsers(
|
||||||
@Args('start', {type: () => GraphQLInt, defaultValue: 0, nullable: true}) start: number,
|
@Args('start', {type: () => Int, defaultValue: 0, nullable: true}) start: number,
|
||||||
@Args('limit', {type: () => GraphQLInt, defaultValue: 50, nullable: true}) limit: number,
|
@Args('limit', {type: () => Int, defaultValue: 50, nullable: true}) limit: number,
|
||||||
@Context('cache') cache: ContextCache,
|
@Context('cache') cache: ContextCache,
|
||||||
): Promise<UserPagerModel> {
|
): Promise<UserPagerModel> {
|
||||||
const [entities, total] = await this.userService.find(start, limit)
|
const [entities, total] = await this.userService.find(start, limit)
|
||||||
28
src/resolver/user/user.query.ts
Normal file
28
src/resolver/user/user.query.ts
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
import { Injectable } from '@nestjs/common'
|
||||||
|
import { Args, Context, ID, Query } from '@nestjs/graphql'
|
||||||
|
import { Roles } from '../../decorator/roles.decorator'
|
||||||
|
import { UserModel } from '../../dto/user/user.model'
|
||||||
|
import { UserEntity } from '../../entity/user.entity'
|
||||||
|
import { UserService } from '../../service/user/user.service'
|
||||||
|
import { ContextCache } from '../context.cache'
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class UserQuery {
|
||||||
|
constructor(
|
||||||
|
private readonly userService: UserService,
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Query(() => UserModel)
|
||||||
|
@Roles('admin')
|
||||||
|
public async getUserById(
|
||||||
|
@Args('id', {type: () => ID}) id: string,
|
||||||
|
@Context('cache') cache: ContextCache,
|
||||||
|
): Promise<UserModel> {
|
||||||
|
const user = await this.userService.findById(id)
|
||||||
|
|
||||||
|
cache.add(cache.getCacheKey(UserEntity.name, user.id), user)
|
||||||
|
|
||||||
|
return new UserModel(user)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,4 +1,4 @@
|
|||||||
import { Args, Context, ID, Parent, Query, ResolveField, Resolver } from '@nestjs/graphql'
|
import { Context, Parent, ResolveField, Resolver } from '@nestjs/graphql'
|
||||||
import { Roles } from '../../decorator/roles.decorator'
|
import { Roles } from '../../decorator/roles.decorator'
|
||||||
import { User } from '../../decorator/user.decorator'
|
import { User } from '../../decorator/user.decorator'
|
||||||
import { UserModel } from '../../dto/user/user.model'
|
import { UserModel } from '../../dto/user/user.model'
|
||||||
@ -13,22 +13,9 @@ export class UserResolver {
|
|||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Query(() => UserModel)
|
@ResolveField(() => [String])
|
||||||
@Roles('admin')
|
|
||||||
public async getUserById(
|
|
||||||
@Args('id', {type: () => ID}) id: string,
|
|
||||||
@Context('cache') cache: ContextCache,
|
|
||||||
): Promise<UserModel> {
|
|
||||||
const user = await this.userService.findById(id)
|
|
||||||
|
|
||||||
cache.add(cache.getCacheKey(UserEntity.name, user.id), user)
|
|
||||||
|
|
||||||
return new UserModel(user)
|
|
||||||
}
|
|
||||||
|
|
||||||
@ResolveField('roles', () => [String])
|
|
||||||
@Roles('user')
|
@Roles('user')
|
||||||
async getRoles(
|
async roles(
|
||||||
@User() user: UserEntity,
|
@User() user: UserEntity,
|
||||||
@Parent() parent: UserModel,
|
@Parent() parent: UserModel,
|
||||||
@Context('cache') cache: ContextCache,
|
@Context('cache') cache: ContextCache,
|
||||||
@ -40,7 +27,7 @@ export class UserResolver {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
returnFieldForSuperuser<T>(
|
private returnFieldForSuperuser<T>(
|
||||||
parent: UserEntity,
|
parent: UserEntity,
|
||||||
user: UserEntity,
|
user: UserEntity,
|
||||||
callback: (user: UserEntity) => T
|
callback: (user: UserEntity) => T
|
||||||
|
|||||||
11
src/resolver/user/user.statistic.query.ts
Normal file
11
src/resolver/user/user.statistic.query.ts
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import { Injectable } from '@nestjs/common'
|
||||||
|
import { Query } from '@nestjs/graphql'
|
||||||
|
import { UserStatisticModel } from '../../dto/user/user.statistic.model'
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class UserStatisticQuery {
|
||||||
|
@Query(() => UserStatisticModel)
|
||||||
|
getUserStatistic(): UserStatisticModel {
|
||||||
|
return new UserStatisticModel()
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,4 +1,4 @@
|
|||||||
import { Int, Query, ResolveField, Resolver } from '@nestjs/graphql'
|
import { Int, ResolveField, Resolver } from '@nestjs/graphql'
|
||||||
import { Roles } from '../../decorator/roles.decorator'
|
import { Roles } from '../../decorator/roles.decorator'
|
||||||
import { UserStatisticModel } from '../../dto/user/user.statistic.model'
|
import { UserStatisticModel } from '../../dto/user/user.statistic.model'
|
||||||
import { UserStatisticService } from '../../service/user/user.statistic.service'
|
import { UserStatisticService } from '../../service/user/user.statistic.service'
|
||||||
@ -10,14 +10,9 @@ export class UserStatisticResolver {
|
|||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Query(() => UserStatisticModel)
|
@ResolveField(() => Int)
|
||||||
getUserStatistic(): UserStatisticModel {
|
|
||||||
return new UserStatisticModel()
|
|
||||||
}
|
|
||||||
|
|
||||||
@ResolveField('total', () => Int)
|
|
||||||
@Roles('admin')
|
@Roles('admin')
|
||||||
getTotal(): Promise<number> {
|
total(): Promise<number> {
|
||||||
return this.statisticService.getTotal()
|
return this.statisticService.getTotal()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -43,7 +43,15 @@ export class SubmissionService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async findById(id: string): Promise<SubmissionEntity> {
|
async findById(id: string): Promise<SubmissionEntity> {
|
||||||
const submission = await this.submissionRepository.findOne(id);
|
const submission = await this.submissionRepository.findOne(
|
||||||
|
id,
|
||||||
|
{
|
||||||
|
relations: [
|
||||||
|
'form',
|
||||||
|
'form.admin',
|
||||||
|
],
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
if (!submission) {
|
if (!submission) {
|
||||||
throw new Error('no form found')
|
throw new Error('no form found')
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user