formPage done

This commit is contained in:
OkaykOrhmn 2025-07-14 10:30:21 +03:30
parent 844e8f40c1
commit 5d81857598
7 changed files with 214 additions and 5 deletions

View File

@ -0,0 +1,17 @@
import { IsString, ValidateNested, IsArray } from 'class-validator';
import { Type } from 'class-transformer';
import { BaseDto } from '../../_core/dto/base.dto';
import { CreateFormSectionDto } from '../../formSection/dto/create-formSection.dto';
export class CreateFormPageDto extends BaseDto {
@IsString()
title: string;
@IsString()
description: string;
@IsArray()
@ValidateNested({ each: true })
@Type(() => CreateFormSectionDto)
formSections: CreateFormSectionDto[];
}

View File

@ -0,0 +1,4 @@
import { PartialType } from '@nestjs/mapped-types';
import { CreateFormPageDto } from './create-formPage.dto';
export class UpdateFormPageDto extends PartialType(CreateFormPageDto) {}

View File

@ -0,0 +1,45 @@
import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
import { Document } from 'mongoose';
import { BaseEntity } from 'src/_core/entity/_base.entity';
import * as mongoosePaginate from 'mongoose-paginate-v2';
import { Attachment, AttachmentSchema } from '../../attachment/entity/attachment.entity';
import { Option, OptionSchema } from '../../option/entity/option.entity';
import { Answer, AnswerSchema } from '../../answer/entity/answer.entity';
import { Question, QuestionSchema } from '../../question/entity/question.entity';
import { FormSection, FormSectionSchema } from '../../formSection/entity/formSection.entity';
@Schema({ _id: false, id: false }) // Disable _id and virtual id
export class FormPage extends BaseEntity {
@Prop({
type: String,
required: true,
})
title: string;
@Prop({
type: String,
required: true,
})
description: string;
@Prop({
type: [FormSectionSchema],
default: [],
})
attachments: FormSection[];
}
export type FormPageDocument = FormPage & Document;
export const FormPageSchema = SchemaFactory.createForClass(FormPage);
FormPageSchema.plugin(mongoosePaginate);
// Transform the output to remove the internal '_id'
FormPageSchema.set('toJSON', {
transform: (doc: FormPageDocument, ret: FormPage & { _id?: any }) => {
delete ret._id;
return ret;
},
});

View File

@ -0,0 +1,47 @@
import { Controller, Get, Post, Patch, Delete, Param, Body, UsePipes, ValidationPipe, Query, ParseUUIDPipe, HttpCode, HttpStatus,} from '@nestjs/common';
import { FormPageService } from './formPage.service';
import { CreateFormPageDto } from './dto/create-formPage.dto';
import { UpdateFormPageDto } from './dto/update-formPage.dto';
import { FormPage } from './entity/formPage.entity';
@Controller('formPages')
export class FormPageController {
constructor(private readonly formPageService: FormPageService) {}
@Post()
@UsePipes(new ValidationPipe({ transform: true, whitelist: true }))
async create(@Body() body: CreateFormPageDto): Promise<FormPage> {
return this.formPageService.create(body);
}
@Get('findAll')
async findAll(
@Query('page') page: string = '1',
@Query('limit') limit: string = '10',
) {
// The service returns the full pagination object
return this.formPageService.findAll(parseInt(page, 10), parseInt(limit, 10));
}
@Get(':id')
async findOne(
@Param('id', new ParseUUIDPipe()) id: string,
): Promise<FormPage | null> {
return this.formPageService.findById(id);
}
@Patch(':id')
@UsePipes(new ValidationPipe({ transform: true, whitelist: true }))
async update(
@Param('id', new ParseUUIDPipe()) id: string,
@Body() body: UpdateFormPageDto,
): Promise<FormPage | null> {
return this.formPageService.update(id, body);
}
@Delete(':id')
@HttpCode(HttpStatus.NO_CONTENT)
async remove(@Param('id', new ParseUUIDPipe()) id: string): Promise<void> {
return this.formPageService.remove(id);
}
}

View File

@ -0,0 +1,16 @@
import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';
import { FormPageService } from './formPage.service';
import { FormPageController } from './formPage.controller';
import { FormPage, FormPageSchema } from './entity/formPage.entity';
@Module({
imports: [
MongooseModule.forFeature([
{ name: FormPage.name, schema: FormPageSchema },
]),
],
controllers: [FormPageController],
providers: [FormPageService],
})
export class FormPageModule {}

View File

@ -0,0 +1,82 @@
import { Injectable, NotFoundException } from '@nestjs/common';
import { InjectModel } from '@nestjs/mongoose';
import { Model } from 'mongoose';
import { FormPage, FormPageDocument } from './entity/formPage.entity';
import { CreateFormPageDto } from './dto/create-formPage.dto';
import { UpdateFormPageDto } from './dto/update-formPage.dto';
import { PaginateModel } from '../participant/participant.service';
@Injectable()
export class FormPageService {
constructor(
@InjectModel(FormPage.name)
private readonly formPageModel: PaginateModel<FormPageDocument>,
) {}
async create(data: CreateFormPageDto): Promise<FormPage> {
const formPage = new this.formPageModel({
...data,
id: data.id || undefined, // Let BaseEntity generate UUID if not provided
metadata: data.metadata || { entries: [] },
});
return formPage.save();
}
async findAll(
page = 1,
limit = 10,
): Promise<{
docs: FormPage[];
totalDocs: number;
limit: number;
page: number;
totalPages: number;
hasNextPage: boolean;
hasPrevPage: boolean;
nextPage: number | null;
prevPage: number | null;
}> {
// Selects all fields from the FormPage entity for the response
return this.formPageModel.paginate(
{},
{ page, limit, lean: true },
);
}
async findById(id: string): Promise<FormPage | null> {
const formPage = await this.formPageModel
.findOne({ id })
.lean()
.exec();
if (!formPage) {
throw new NotFoundException(`FormPage with ID "${id}" not found`);
}
return formPage;
}
async update(
id: string,
data: UpdateFormPageDto,
): Promise<FormPage | null> {
const updatedFormPage = await this.formPageModel
.findOneAndUpdate(
{ id },
{ $set: { ...data, updatedAt: new Date() } },
{ new: true },
)
.lean()
.exec();
if (!updatedFormPage) {
throw new NotFoundException(`FormPage with ID "${id}" not found`);
}
return updatedFormPage;
}
async remove(id: string): Promise<void> {
const result = await this.formPageModel.deleteOne({ id }).exec();
if (result.deletedCount === 0) {
throw new NotFoundException(`FormPage with ID "${id}" not found`);
}
}
}

View File

@ -1,7 +1,7 @@
import { IsString, IsOptional, IsUUID, ValidateNested, IsArray, IsEnum, IsDateString } from 'class-validator'; import { IsString, IsOptional, IsUUID, ValidateNested, IsArray, IsEnum, IsDateString } from 'class-validator';
import { Type } from 'class-transformer'; import { Type } from 'class-transformer';
import { BaseDto } from '../../_core/dto/base.dto'; import { BaseDto } from '../../_core/dto/base.dto';
import { CreateAttachmentDto } from '../../attachment/dto/create-attachment.dto'; import { CreateAttachmentDto } from '../../attachment/dto/create_attachment.dto';
import { CreateQuestionDto } from '../../question/dto/create-question.dto'; import { CreateQuestionDto } from '../../question/dto/create-question.dto';
// DTO for DisplayCondition // DTO for DisplayCondition
@ -32,12 +32,10 @@ export class CreateFormSectionDto extends BaseDto {
@IsArray() @IsArray()
@ValidateNested({ each: true }) @ValidateNested({ each: true })
@Type(() => CreateDisplayConditionDto) @Type(() => CreateDisplayConditionDto)
@IsOptional() displayCondition: CreateDisplayConditionDto[];
displayCondition?: CreateDisplayConditionDto[];
@IsArray() @IsArray()
@ValidateNested({ each: true }) @ValidateNested({ each: true })
@Type(() => CreateQuestionDto) @Type(() => CreateQuestionDto)
@IsOptional() questions: CreateQuestionDto[];
questions?: CreateQuestionDto[];
} }