Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Build services/controller for creating form templates #29

Merged
merged 12 commits into from
Sep 24, 2023
15,454 changes: 15,454 additions & 0 deletions apps/server/package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion apps/server/src/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import { ConfigModule } from '@nestjs/config';
DepartmentsModule,
ConfigModule.forRoot({
envFilePath: '.env',
})
}),
],
controllers: [AppController],
providers: [AppService],
Expand Down
14 changes: 13 additions & 1 deletion apps/server/src/form-instances/entities/form-instance.entity.ts
Original file line number Diff line number Diff line change
@@ -1 +1,13 @@
export class FormInstance {}
import { FormInstance } from '@prisma/client';

export class FormInstanceEntity implements FormInstance {
// placeholder
id: string;
name: string;
formDocLink: string;
completed: boolean;
createdAt: Date;
updatedAt: Date;
originatorId: string;
formTemplateId: string;
}
26 changes: 25 additions & 1 deletion apps/server/src/form-templates/dto/create-form-template.dto.ts
Original file line number Diff line number Diff line change
@@ -1 +1,25 @@
export class CreateFormTemplateDto {}
import { ApiProperty } from '@nestjs/swagger';
import {
IsNotEmpty,
IsString,
IsUrl,
IsArray,
} from 'class-validator';
import { SignatureField } from '@prisma/client';

export class CreateFormTemplateDto {
@IsString()
@IsNotEmpty()
@ApiProperty()
name: string;

@IsString()
@IsNotEmpty()
@IsUrl()
@ApiProperty()
formDocLink: string;

@IsArray()
@ApiProperty()
signatureFields: SignatureField[];
}
33 changes: 32 additions & 1 deletion apps/server/src/form-templates/entities/form-template.entity.ts
Original file line number Diff line number Diff line change
@@ -1 +1,32 @@
export class FormTemplate {}
import { ApiProperty } from '@nestjs/swagger';
import { FormTemplate } from '@prisma/client';
import { Exclude } from 'class-transformer';
import { SignatureFieldEntity } from './../../signature-fields/entities/signature-field.entity';
import { FormInstanceEntity } from './../../form-instances/entities/form-instance.entity';

export class FormTemplateEntity implements FormTemplate {
@ApiProperty()
id: string;

@ApiProperty()
name: string;

@ApiProperty()
formDocLink: string;

@Exclude()
createdAt: Date;

@Exclude()
updatedAt: Date;

@ApiProperty()
signatureFields: SignatureFieldEntity[];

@ApiProperty()
formInstances: FormInstanceEntity[];

constructor(partial: Partial<FormTemplateEntity>) {
Object.assign(this, partial);
}
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import { Test, TestingModule } from '@nestjs/testing';
import { FormTemplatesController } from './form-templates.controller';
import { FormTemplatesService } from './form-templates.service';
import { PrismaService } from './../../../server/src/prisma/prisma.service';

describe('FormTemplatesController', () => {
let controller: FormTemplatesController;

beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
controllers: [FormTemplatesController],
providers: [FormTemplatesService],
providers: [FormTemplatesService, PrismaService],
}).compile();

controller = module.get<FormTemplatesController>(FormTemplatesController);
Expand Down
152 changes: 117 additions & 35 deletions apps/server/src/form-templates/form-templates.controller.ts
Original file line number Diff line number Diff line change
@@ -1,45 +1,127 @@
import {
Controller,
// Get,
// Post,
// Body,
// Patch,
// Param,
// Delete,
Get,
Post,
Body,
Patch,
Param,
Delete,
NotFoundException,
Query,
} from '@nestjs/common';
import { FormTemplatesService } from './form-templates.service';
// import { CreateFormTemplateDto } from './dto/create-form-template.dto';
// import { UpdateFormTemplateDto } from './dto/update-form-template.dto';
import {
ApiBadRequestResponse,
ApiCreatedResponse,
ApiForbiddenResponse,
ApiNotFoundResponse,
ApiOkResponse,
ApiTags,
ApiUnprocessableEntityResponse,
} from '@nestjs/swagger';
import { FormTemplateEntity } from './entities/form-template.entity';
import { AppErrorMessage } from '../app.errors';
import { CreateFormTemplateDto } from './dto/create-form-template.dto';
import { FormTemplateErrorMessage } from './form-templates.errors';
import { UpdateFormTemplateDto } from './dto/update-form-template.dto';
import { Prisma } from '@prisma/client';

@ApiTags('form-templates')
@Controller('form-templates')
export class FormTemplatesController {
constructor(private readonly formTemplatesService: FormTemplatesService) {}

// @Post()
// create(@Body() createFormTemplateDto: CreateFormTemplateDto) {
// return this.formTemplatesService.create(createFormTemplateDto);
// }

// @Get()
// findAll() {
// return this.formTemplatesService.findAll();
// }

// @Get(':id')
// findOne(@Param('id') id: string) {
// return this.formTemplatesService.findOne(+id);
// }

// @Patch(':id')
// update(
// @Param('id') id: string,
// @Body() updateFormTemplateDto: UpdateFormTemplateDto,
// ) {
// return this.formTemplatesService.update(+id, updateFormTemplateDto);
// }

// @Delete(':id')
// remove(@Param('id') id: string) {
// return this.formTemplatesService.remove(+id);
// }
@Post()
@ApiCreatedResponse({ type: FormTemplateEntity })
@ApiForbiddenResponse({ description: AppErrorMessage.FORBIDDEN })
@ApiUnprocessableEntityResponse({
description: AppErrorMessage.UNPROCESSABLE_ENTITY,
})
async create(@Body() createFormTemplateDto: CreateFormTemplateDto) {
const newFormTemplate = await this.formTemplatesService.create(
createFormTemplateDto,
);
return new FormTemplateEntity(newFormTemplate);
}

@Get()
@ApiOkResponse({ type: [FormTemplateEntity] })
@ApiForbiddenResponse({ description: AppErrorMessage.FORBIDDEN })
@ApiBadRequestResponse({ description: AppErrorMessage.UNPROCESSABLE_ENTITY })
async findAll(@Query('limit') limit?: number) {
const formTemplates = await this.formTemplatesService.findAll(limit);
return formTemplates.map(
(formTemplate) => new FormTemplateEntity(formTemplate),
);
}

@Get(':id')
@ApiOkResponse({ type: FormTemplateEntity })
@ApiForbiddenResponse({ description: AppErrorMessage.FORBIDDEN })
@ApiNotFoundResponse({ description: AppErrorMessage.NOT_FOUND })
@ApiBadRequestResponse({ description: AppErrorMessage.UNPROCESSABLE_ENTITY })
async findOne(@Param('id') id: string) {
const formTemplate = await this.formTemplatesService.findOne(id);

if (formTemplate == null) {
console.log(FormTemplateErrorMessage.FORM_TEMPLATE_NOT_FOUND);
throw new NotFoundException(
FormTemplateErrorMessage.FORM_TEMPLATE_NOT_FOUND,
);
}

return new FormTemplateEntity(formTemplate);
}

@Patch(':id')
@ApiOkResponse({ type: FormTemplateEntity })
@ApiForbiddenResponse({ description: AppErrorMessage.FORBIDDEN })
@ApiNotFoundResponse({ description: AppErrorMessage.NOT_FOUND })
@ApiUnprocessableEntityResponse({
description: AppErrorMessage.UNPROCESSABLE_ENTITY,
})
@ApiBadRequestResponse({ description: AppErrorMessage.UNPROCESSABLE_ENTITY })
async update(
@Param('id') id: string,
@Body() updateFormTemplateDto: UpdateFormTemplateDto,
) {
try {
const updatedFormTemplate = await this.formTemplatesService.update(
id,
updateFormTemplateDto,
);
return new FormTemplateEntity(updatedFormTemplate);
} catch (e) {
if (e instanceof Prisma.PrismaClientKnownRequestError) {
if (e.code === 'P2025') {
console.log(FormTemplateErrorMessage.FORM_TEMPLATE_NOT_FOUND);
throw new NotFoundException(
FormTemplateErrorMessage.FORM_TEMPLATE_NOT_FOUND,
);
}
}
throw e;
}
}

@Delete(':id')
@ApiOkResponse()
@ApiForbiddenResponse({ description: AppErrorMessage.FORBIDDEN })
@ApiNotFoundResponse({ description: AppErrorMessage.NOT_FOUND })
@ApiBadRequestResponse({ description: AppErrorMessage.UNPROCESSABLE_ENTITY })
async remove(@Param('id') id: string) {
try {
await this.formTemplatesService.remove(id);
} catch (e) {
if (e instanceof Prisma.PrismaClientKnownRequestError) {
if (e.code === 'P2025') {
console.log(FormTemplateErrorMessage.FORM_TEMPLATE_NOT_FOUND);
throw new NotFoundException(
FormTemplateErrorMessage.FORM_TEMPLATE_NOT_FOUND,
);
}
}
throw e;
}
}
}
4 changes: 4 additions & 0 deletions apps/server/src/form-templates/form-templates.errors.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export enum FormTemplateErrorMessage {
FORM_TEMPLATE_NOT_FOUND = 'Form template could not be found with this id',
FORM_TEMPLATE_NOT_FOUND_CLIENT = 'Form template could not be found',
}
2 changes: 2 additions & 0 deletions apps/server/src/form-templates/form-templates.module.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { Module } from '@nestjs/common';
import { FormTemplatesService } from './form-templates.service';
import { FormTemplatesController } from './form-templates.controller';
import { PrismaModule } from '../prisma/prisma.module';

@Module({
controllers: [FormTemplatesController],
providers: [FormTemplatesService],
imports: [PrismaModule],
})
export class FormTemplatesModule {}
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { Test, TestingModule } from '@nestjs/testing';
import { FormTemplatesService } from './form-templates.service';
import { PrismaService } from './../../../server/src/prisma/prisma.service';

describe('FormTemplatesService', () => {
let service: FormTemplatesService;

beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [FormTemplatesService],
providers: [FormTemplatesService, PrismaService],
}).compile();

service = module.get<FormTemplatesService>(FormTemplatesService);
Expand Down
96 changes: 79 additions & 17 deletions apps/server/src/form-templates/form-templates.service.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,84 @@
import { Injectable } from '@nestjs/common';
// import { CreateFormTemplateDto } from './dto/create-form-template.dto';
// import { UpdateFormTemplateDto } from './dto/update-form-template.dto';
import { CreateFormTemplateDto } from './dto/create-form-template.dto';
import { UpdateFormTemplateDto } from './dto/update-form-template.dto';
import { PrismaService } from '../prisma/prisma.service';

@Injectable()
export class FormTemplatesService {
// create(createFormTemplateDto: CreateFormTemplateDto) {
// return 'This action adds a new formTemplate';
// }
// findAll() {
// return `This action returns all formTemplates`;
// }
// findOne(id: number) {
// return `This action returns a #${id} formTemplate`;
// }
// update(id: number, updateFormTemplateDto: UpdateFormTemplateDto) {
// return `This action updates a #${id} formTemplate`;
// }
// remove(id: number) {
// return `This action removes a #${id} formTemplate`;
// }
constructor(private prisma: PrismaService) {}

/**
* Create a new form template.
* @param createFormTemplateDto create form template dto
* @returns the created employee, hydrated
*/
async create(createFormTemplateDto: CreateFormTemplateDto) {
const newFormTemplate = await this.prisma.formTemplate.create({
data: {
name: createFormTemplateDto.name,
formDocLink: createFormTemplateDto.formDocLink,
// signatureFields: { create: createFormTemplateDto.signatureFields },
},
});
return newFormTemplate;
}

/**
* Retrieve all form templates.
* @param limit the number of form templates we want to retrieve (optional)
* @returns all form templates, hydrated
*/
async findAll(limit?: number) {
const formTemplates = await this.prisma.formTemplate.findMany({
take: limit,
});
return formTemplates;
}

/**
* Retrieve a form template by id.
* @param id the form template id
* @returns the selected form template, hydrated
*/
async findOne(id: string) {
const formTemplate = await this.prisma.formTemplate.findFirstOrThrow({
where: {
id: id,
},
});

return formTemplate;
}

/**
* Update a form template.
* @param id the form template id
* @param updateFormTemplateDto update form template dto
* @returns the updated form template, hydrated
*/
async update(id: string, updateFormTemplateDto: UpdateFormTemplateDto) {
const updatedFormTemplate = await this.prisma.formTemplate.update({
where: {
id: id,
},
data: {
name: updateFormTemplateDto.name,
formDocLink: updateFormTemplateDto.formDocLink,
signatureFields: { create: updateFormTemplateDto.signatureFields },
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

comment this out for now, we need to think about how updating the signature fields will work

},
});
return updatedFormTemplate;
}

/**
* Remove a form template.
* @param id the form template id
*/
async remove(id: string) {
await this.prisma.formTemplate.delete({
where: {
id: id,
},
});
}
}
Loading