answer done
This commit is contained in:
parent
a74932f8bb
commit
89f0fdbb60
|
|
@ -0,0 +1,47 @@
|
||||||
|
import { Controller, Get, Post, Patch, Delete, Param, Body, UsePipes, ValidationPipe, Query, ParseUUIDPipe, HttpCode, HttpStatus,} from '@nestjs/common';
|
||||||
|
import { AnswerService } from './answer.service';
|
||||||
|
import { CreateAnswerDto } from './dto/create-answer.dto';
|
||||||
|
import { UpdateAnswerDto } from './dto/update-answer.dto';
|
||||||
|
import { Answer } from './entity/answer.entity';
|
||||||
|
|
||||||
|
@Controller('answers')
|
||||||
|
export class AnswerController {
|
||||||
|
constructor(private readonly answerService: AnswerService) {}
|
||||||
|
|
||||||
|
@Post()
|
||||||
|
@UsePipes(new ValidationPipe({ transform: true, whitelist: true }))
|
||||||
|
async create(@Body() body: CreateAnswerDto): Promise<Answer> {
|
||||||
|
return this.answerService.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.answerService.findAll(parseInt(page, 10), parseInt(limit, 10));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Get(':id')
|
||||||
|
async findOne(
|
||||||
|
@Param('id', new ParseUUIDPipe()) id: string,
|
||||||
|
): Promise<Answer | null> {
|
||||||
|
return this.answerService.findById(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Patch(':id')
|
||||||
|
@UsePipes(new ValidationPipe({ transform: true, whitelist: true }))
|
||||||
|
async update(
|
||||||
|
@Param('id', new ParseUUIDPipe()) id: string,
|
||||||
|
@Body() body: UpdateAnswerDto,
|
||||||
|
): Promise<Answer | null> {
|
||||||
|
return this.answerService.update(id, body);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Delete(':id')
|
||||||
|
@HttpCode(HttpStatus.NO_CONTENT)
|
||||||
|
async remove(@Param('id', new ParseUUIDPipe()) id: string): Promise<void> {
|
||||||
|
return this.answerService.remove(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
import { Module } from '@nestjs/common';
|
||||||
|
import { MongooseModule } from '@nestjs/mongoose';
|
||||||
|
import { AnswerService } from './answer.service';
|
||||||
|
import { AnswerController } from './answer.controller';
|
||||||
|
import { Answer, AnswerSchema } from './entity/answer.entity';
|
||||||
|
|
||||||
|
@Module({
|
||||||
|
imports: [
|
||||||
|
MongooseModule.forFeature([
|
||||||
|
{ name: Answer.name, schema: AnswerSchema },
|
||||||
|
]),
|
||||||
|
],
|
||||||
|
controllers: [AnswerController],
|
||||||
|
providers: [AnswerService],
|
||||||
|
})
|
||||||
|
export class AnswerModule {}
|
||||||
|
|
@ -0,0 +1,81 @@
|
||||||
|
import { Injectable, NotFoundException } from '@nestjs/common';
|
||||||
|
import { InjectModel } from '@nestjs/mongoose';
|
||||||
|
import { Model } from 'mongoose';
|
||||||
|
import { Answer, AnswerDocument } from './entity/answer.entity';
|
||||||
|
import { CreateAnswerDto } from './dto/create-answer.dto';
|
||||||
|
import { UpdateAnswerDto } from './dto/update-answer.dto';
|
||||||
|
import { PaginateModel } from '../participant/participant.service';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class AnswerService {
|
||||||
|
constructor(
|
||||||
|
@InjectModel(Answer.name)
|
||||||
|
private readonly answerModel: PaginateModel<AnswerDocument>,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
async create(data: CreateAnswerDto): Promise<Answer> {
|
||||||
|
const answer = new this.answerModel({
|
||||||
|
...data,
|
||||||
|
id: data.id || undefined, // Let BaseEntity generate UUID if not provided
|
||||||
|
metadata: data.metadata || { entries: [] },
|
||||||
|
});
|
||||||
|
return answer.save();
|
||||||
|
}
|
||||||
|
|
||||||
|
async findAll(
|
||||||
|
page = 1,
|
||||||
|
limit = 10,
|
||||||
|
): Promise<{
|
||||||
|
docs: Answer[];
|
||||||
|
totalDocs: number;
|
||||||
|
limit: number;
|
||||||
|
page: number;
|
||||||
|
totalPages: number;
|
||||||
|
hasNextPage: boolean;
|
||||||
|
hasPrevPage: boolean;
|
||||||
|
nextPage: number | null;
|
||||||
|
prevPage: number | null;
|
||||||
|
}> {
|
||||||
|
return this.answerModel.paginate(
|
||||||
|
{},
|
||||||
|
{ page, limit, lean: true },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
async findById(id: string): Promise<Answer | null> {
|
||||||
|
const answer = await this.answerModel
|
||||||
|
.findOne({ id })
|
||||||
|
.lean()
|
||||||
|
.exec();
|
||||||
|
if (!answer) {
|
||||||
|
throw new NotFoundException(`Answer with ID "${id}" not found`);
|
||||||
|
}
|
||||||
|
return answer;
|
||||||
|
}
|
||||||
|
|
||||||
|
async update(
|
||||||
|
id: string,
|
||||||
|
data: UpdateAnswerDto,
|
||||||
|
): Promise<Answer | null> {
|
||||||
|
const updatedAnswer = await this.answerModel
|
||||||
|
.findOneAndUpdate(
|
||||||
|
{ id },
|
||||||
|
{ $set: { ...data, updatedAt: new Date() } },
|
||||||
|
{ new: true },
|
||||||
|
)
|
||||||
|
.lean()
|
||||||
|
.exec();
|
||||||
|
|
||||||
|
if (!updatedAnswer) {
|
||||||
|
throw new NotFoundException(`Answer with ID "${id}" not found`);
|
||||||
|
}
|
||||||
|
return updatedAnswer;
|
||||||
|
}
|
||||||
|
|
||||||
|
async remove(id: string): Promise<void> {
|
||||||
|
const result = await this.answerModel.deleteOne({ id }).exec();
|
||||||
|
if (result.deletedCount === 0) {
|
||||||
|
throw new NotFoundException(`Answer with ID "${id}" not found`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
import { IsString, IsUUID} from 'class-validator';
|
||||||
|
import { BaseDto } from '../../_core/dto/base.dto';
|
||||||
|
|
||||||
|
export class CreateAnswerDto extends BaseDto{
|
||||||
|
@IsUUID()
|
||||||
|
participantId: string;
|
||||||
|
|
||||||
|
@IsUUID()
|
||||||
|
questionId: string;
|
||||||
|
|
||||||
|
@IsString()
|
||||||
|
value: string;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
import { PartialType } from '@nestjs/mapped-types';
|
||||||
|
import { CreateAnswerDto } from './create-answer.dto';
|
||||||
|
|
||||||
|
export class UpdateAnswerDto extends PartialType(CreateAnswerDto) {}
|
||||||
|
|
@ -0,0 +1,44 @@
|
||||||
|
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 { v4 as uuidv4 } from 'uuid';
|
||||||
|
|
||||||
|
@Schema({ _id: false, id: false }) // Disable _id and virtual id
|
||||||
|
export class Answer extends BaseEntity {
|
||||||
|
@Prop({
|
||||||
|
type: String,
|
||||||
|
default: () => uuidv4(),
|
||||||
|
required: true,
|
||||||
|
immutable: true,
|
||||||
|
})
|
||||||
|
participantId: string;
|
||||||
|
|
||||||
|
@Prop({
|
||||||
|
type: String,
|
||||||
|
default: () => uuidv4(),
|
||||||
|
required: true,
|
||||||
|
immutable: true,
|
||||||
|
})
|
||||||
|
questionId: string; // form can be identified based on question
|
||||||
|
|
||||||
|
@Prop({
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
})
|
||||||
|
value: string; //value can be mapped to option based on question type
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export type AnswerDocument = Answer & Document;
|
||||||
|
export const AnswerSchema = SchemaFactory.createForClass(Answer);
|
||||||
|
AnswerSchema.plugin(mongoosePaginate);
|
||||||
|
|
||||||
|
// Transform the output to remove the internal '_id'
|
||||||
|
AnswerSchema.set('toJSON', {
|
||||||
|
transform: (doc: AnswerDocument, ret: Answer & { _id?: any }) => {
|
||||||
|
delete ret._id;
|
||||||
|
return ret;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
@ -4,24 +4,8 @@ import { Model } from 'mongoose';
|
||||||
import { Attachment, AttachmentDocument } from './entity/attachment.entity';
|
import { Attachment, AttachmentDocument } from './entity/attachment.entity';
|
||||||
import { CreateAttachmentDto } from './dto/create_attachment.dto';
|
import { CreateAttachmentDto } from './dto/create_attachment.dto';
|
||||||
import { UpdateAttachmentDto } from './dto/update_attachment.dto';
|
import { UpdateAttachmentDto } from './dto/update_attachment.dto';
|
||||||
|
import { PaginateModel } from '../participant/participant.service';
|
||||||
|
|
||||||
// Interface matching the mongoose-paginate-v2 plugin
|
|
||||||
interface PaginateModel<T> extends Model<T> {
|
|
||||||
paginate: (
|
|
||||||
query?: any,
|
|
||||||
options?: { page: number; limit: number; lean?: boolean; select?: string },
|
|
||||||
) => Promise<{
|
|
||||||
docs: T[];
|
|
||||||
totalDocs: number;
|
|
||||||
limit: number;
|
|
||||||
page: number;
|
|
||||||
totalPages: number;
|
|
||||||
hasNextPage: boolean;
|
|
||||||
hasPrevPage: boolean;
|
|
||||||
nextPage: number | null;
|
|
||||||
prevPage: number | null;
|
|
||||||
}>;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class AttachmentService {
|
export class AttachmentService {
|
||||||
|
|
@ -54,20 +38,15 @@ export class AttachmentService {
|
||||||
prevPage: number | null;
|
prevPage: number | null;
|
||||||
}> {
|
}> {
|
||||||
// Selects all fields from the Attachment entity for the response
|
// Selects all fields from the Attachment entity for the response
|
||||||
const selectFields =
|
|
||||||
'id text type isRequired isConfidential validationRules options attachments metadata status createdAt updatedAt';
|
|
||||||
return this.attachmentModel.paginate(
|
return this.attachmentModel.paginate(
|
||||||
{},
|
{},
|
||||||
{ page, limit, lean: true, select: selectFields },
|
{ page, limit, lean: true },
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
async findById(id: string): Promise<Attachment | null> {
|
async findById(id: string): Promise<Attachment | null> {
|
||||||
const selectFields =
|
|
||||||
'id text type isRequired isConfidential validationRules options attachments metadata status createdAt updatedAt';
|
|
||||||
const attachment = await this.attachmentModel
|
const attachment = await this.attachmentModel
|
||||||
.findOne({ id })
|
.findOne({ id })
|
||||||
.select(selectFields)
|
|
||||||
.lean()
|
.lean()
|
||||||
.exec();
|
.exec();
|
||||||
if (!attachment) {
|
if (!attachment) {
|
||||||
|
|
@ -80,15 +59,12 @@ export class AttachmentService {
|
||||||
id: string,
|
id: string,
|
||||||
data: UpdateAttachmentDto,
|
data: UpdateAttachmentDto,
|
||||||
): Promise<Attachment | null> {
|
): Promise<Attachment | null> {
|
||||||
const selectFields =
|
|
||||||
'id text type isRequired isConfidential validationRules options attachments metadata status createdAt updatedAt';
|
|
||||||
const updatedAttachment = await this.attachmentModel
|
const updatedAttachment = await this.attachmentModel
|
||||||
.findOneAndUpdate(
|
.findOneAndUpdate(
|
||||||
{ id },
|
{ id },
|
||||||
{ $set: { ...data, updatedAt: new Date() } },
|
{ $set: { ...data, updatedAt: new Date() } },
|
||||||
{ new: true },
|
{ new: true },
|
||||||
)
|
)
|
||||||
.select(selectFields)
|
|
||||||
.lean()
|
.lean()
|
||||||
.exec();
|
.exec();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,28 +1,10 @@
|
||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
import { InjectModel } from '@nestjs/mongoose';
|
import { InjectModel } from '@nestjs/mongoose';
|
||||||
import { Model } from 'mongoose';
|
|
||||||
import { CreateOptionDto } from './dto/create-option.dto';
|
import { CreateOptionDto } from './dto/create-option.dto';
|
||||||
import { UpdateOptionDto } from './dto/update-option.dto';
|
import { UpdateOptionDto } from './dto/update-option.dto';
|
||||||
import { Option, OptionDocument } from './entity/option.entity';
|
import { Option, OptionDocument } from './entity/option.entity';
|
||||||
import { PaginateQuery, Paginated, paginate } from 'nestjs-paginate';
|
import { PaginateModel } from '../participant/participant.service';
|
||||||
|
|
||||||
|
|
||||||
interface PaginateModel<T> extends Model<T> {
|
|
||||||
paginate: (
|
|
||||||
query?: any,
|
|
||||||
options?: { page: number; limit: number; lean?: boolean; select?: string },
|
|
||||||
) => Promise<{
|
|
||||||
docs: T[];
|
|
||||||
totalDocs: number;
|
|
||||||
limit: number;
|
|
||||||
page: number;
|
|
||||||
totalPages: number;
|
|
||||||
hasNextPage: boolean;
|
|
||||||
hasPrevPage: boolean;
|
|
||||||
nextPage: number | null;
|
|
||||||
prevPage: number | null;
|
|
||||||
}>;
|
|
||||||
}
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class OptionService {
|
export class OptionService {
|
||||||
constructor(
|
constructor(
|
||||||
|
|
@ -48,7 +30,7 @@ export class OptionService {
|
||||||
}> {
|
}> {
|
||||||
return this.optionModel.paginate(
|
return this.optionModel.paginate(
|
||||||
{},
|
{},
|
||||||
{ page, limit, lean: true, select: 'id metadata status text createdAt updatedAt' },
|
{ page, limit, lean: true },
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ import { Participant, ParticipantDocument } from './entity/participant.entity';
|
||||||
import { UpdateParticipantDto } from './dto/update-participant.dto';
|
import { UpdateParticipantDto } from './dto/update-participant.dto';
|
||||||
import { v4 as uuidv4 } from 'uuid';
|
import { v4 as uuidv4 } from 'uuid';
|
||||||
|
|
||||||
interface PaginateModel<T> extends Model<T> {
|
export interface PaginateModel<T> extends Model<T> {
|
||||||
paginate: (
|
paginate: (
|
||||||
query?: any,
|
query?: any,
|
||||||
options?: { page: number; limit: number; lean?: boolean; select?: string },
|
options?: { page: number; limit: number; lean?: boolean; select?: string },
|
||||||
|
|
@ -52,12 +52,12 @@ export class ParticipantService {
|
||||||
}> {
|
}> {
|
||||||
return this.participantModel.paginate(
|
return this.participantModel.paginate(
|
||||||
{},
|
{},
|
||||||
{ page, limit, lean: true, select: 'id metadata status userId role displayName createdAt updatedAt' },
|
{ page, limit, lean: true},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
async findById(id: string): Promise<Participant | null> {
|
async findById(id: string): Promise<Participant | null> {
|
||||||
return this.participantModel.findOne({ id }).select('id metadata status userId role displayName createdAt updatedAt').lean().exec();
|
return this.participantModel.findOne({ id }).lean().exec();
|
||||||
}
|
}
|
||||||
|
|
||||||
async update(id: string, data: UpdateParticipantDto): Promise<Participant | null> {
|
async update(id: string, data: UpdateParticipantDto): Promise<Participant | null> {
|
||||||
|
|
@ -66,10 +66,7 @@ export class ParticipantService {
|
||||||
{ id },
|
{ id },
|
||||||
{ $set: { ...data, updatedAt: new Date() } },
|
{ $set: { ...data, updatedAt: new Date() } },
|
||||||
{ new: true },
|
{ new: true },
|
||||||
)
|
).lean().exec();
|
||||||
.select('id metadata status userId role displayName createdAt updatedAt')
|
|
||||||
.lean()
|
|
||||||
.exec();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async remove(id: string): Promise<void> {
|
async remove(id: string): Promise<void> {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
import { IsString, IsEnum, IsOptional, IsUUID, ValidateNested } from 'class-validator';
|
||||||
|
import { Type } from 'class-transformer';
|
||||||
|
import { MetadataDto } from '../../_core/dto/metadataEntry.dto';
|
||||||
|
import { BaseDto } from '../../_core/dto/base.dto';
|
||||||
|
|
||||||
|
export class CreateParticipantGroupDto extends BaseDto{
|
||||||
|
@IsString()
|
||||||
|
title: string; // Required, provided by client
|
||||||
|
|
||||||
|
@IsEnum(['confidential','delphi','one-time-question','one-time-section','one-time-page','one-time-form'])
|
||||||
|
type: 'confidential'|'delphi'|'one-time-question'|'one-time-section'|'one-time-page'|'one-time-form';
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
import { PartialType } from '@nestjs/mapped-types';
|
||||||
|
import { CreateParticipantGroupDto } from './create-participantGroup.dto';
|
||||||
|
|
||||||
|
export class UpdateParticipantGroupDto extends PartialType(CreateParticipantGroupDto) {}
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
|
||||||
|
import { BaseEntity } from 'src/_core/entity/_base.entity';
|
||||||
|
import * as mongoosePaginate from 'mongoose-paginate-v2';
|
||||||
|
import { Document } from 'mongoose';
|
||||||
|
|
||||||
|
@Schema({ _id: false, id: false }) // Disable _id and virtual id
|
||||||
|
export class ParticipantGroup extends BaseEntity {
|
||||||
|
@Prop({
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
})
|
||||||
|
title: string;
|
||||||
|
|
||||||
|
@Prop({
|
||||||
|
type: String,
|
||||||
|
enum: ['confidential','delphi','one-time-question','one-time-section','one-time-page','one-time-form'],
|
||||||
|
// default: '',
|
||||||
|
required: true,
|
||||||
|
})
|
||||||
|
type: 'confidential'|'delphi'|'one-time-question'|'one-time-section'|'one-time-page'|'one-time-form';
|
||||||
|
}
|
||||||
|
|
||||||
|
export type ParticipantGroupDocument = ParticipantGroup & Document;
|
||||||
|
export const ParticipantGroupSchema = SchemaFactory.createForClass(ParticipantGroup);
|
||||||
|
ParticipantGroupSchema.plugin(mongoosePaginate);
|
||||||
|
ParticipantGroupSchema.set('toJSON', {
|
||||||
|
transform: (doc: ParticipantGroupDocument, ret: ParticipantGroup & { _id?: any }) => {
|
||||||
|
delete ret._id;
|
||||||
|
return ret;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
@ -0,0 +1,53 @@
|
||||||
|
import { Controller, Get, Post, Patch, Delete, Param, Body, UsePipes, ValidationPipe, Query, ParseUUIDPipe } from '@nestjs/common';
|
||||||
|
import { ParticipantGroupService } from './participantGroup.service';
|
||||||
|
import { CreateParticipantGroupDto } from './dto/create-participantGroup.dto';
|
||||||
|
import { UpdateParticipantGroupDto } from './dto/update-participantGroup.dto';
|
||||||
|
import { ParticipantGroup } from './entity/participantGroup.entity';
|
||||||
|
|
||||||
|
@Controller('participantGroupGroups')
|
||||||
|
export class ParticipantGroupController {
|
||||||
|
constructor(private readonly participantGroupService: ParticipantGroupService) {}
|
||||||
|
|
||||||
|
@Post()
|
||||||
|
@UsePipes(new ValidationPipe({ transform: true }))
|
||||||
|
async create(@Body() body: CreateParticipantGroupDto): Promise<ParticipantGroup> {
|
||||||
|
return this.participantGroupService.create(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Get('findAll') // returns non uuid id !!!
|
||||||
|
async findAll(
|
||||||
|
@Query('page') page: string = '1',
|
||||||
|
@Query('limit') limit: string = '10',
|
||||||
|
): Promise<{
|
||||||
|
docs: ParticipantGroup[];
|
||||||
|
totalDocs: number;
|
||||||
|
limit: number;
|
||||||
|
page: number;
|
||||||
|
totalPages: number;
|
||||||
|
hasNextPage: boolean;
|
||||||
|
hasPrevPage: boolean;
|
||||||
|
nextPage: number | null;
|
||||||
|
prevPage: number | null;
|
||||||
|
}> {
|
||||||
|
return this.participantGroupService.findAll(parseInt(page), parseInt(limit));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Get(':id')
|
||||||
|
async findOne(@Param('id', new ParseUUIDPipe()) id: string): Promise<ParticipantGroup | null> {
|
||||||
|
return this.participantGroupService.findById(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Patch(':id')
|
||||||
|
@UsePipes(new ValidationPipe({ transform: true }))
|
||||||
|
async update(
|
||||||
|
@Param('id', new ParseUUIDPipe()) id: string,
|
||||||
|
@Body() body: UpdateParticipantGroupDto,
|
||||||
|
): Promise<ParticipantGroup | null> {
|
||||||
|
return this.participantGroupService.update(id, body);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Delete(':id')
|
||||||
|
async remove(@Param('id', new ParseUUIDPipe()) id: string): Promise<void> {
|
||||||
|
return this.participantGroupService.remove(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
import { Module } from '@nestjs/common';
|
||||||
|
import { MongooseModule } from '@nestjs/mongoose';
|
||||||
|
import { ParticipantGroupService } from './participantGroup.service';
|
||||||
|
import { ParticipantGroupController } from './participantGroup.controller';
|
||||||
|
import { ParticipantGroup, ParticipantGroupSchema } from './entity/participantGroup.entity';
|
||||||
|
|
||||||
|
@Module({
|
||||||
|
imports: [
|
||||||
|
MongooseModule.forFeature([{ name: ParticipantGroup.name, schema: ParticipantGroupSchema }]),
|
||||||
|
],
|
||||||
|
controllers: [ParticipantGroupController],
|
||||||
|
providers: [ParticipantGroupService],
|
||||||
|
})
|
||||||
|
export class ParticipanGrouptModule {}
|
||||||
|
|
@ -0,0 +1,60 @@
|
||||||
|
import { Injectable } from '@nestjs/common';
|
||||||
|
import { InjectModel } from '@nestjs/mongoose';
|
||||||
|
import { Model } from 'mongoose';
|
||||||
|
import { CreateParticipantGroupDto } from './dto/create-participantGroup.dto';
|
||||||
|
import { ParticipantGroup, ParticipantGroupDocument } from './entity/participantGroup.entity';
|
||||||
|
import { UpdateParticipantGroupDto } from './dto/update-participantGroup.dto';
|
||||||
|
import { v4 as uuidv4 } from 'uuid';
|
||||||
|
import { PaginateModel } from '../participant/participant.service';
|
||||||
|
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class ParticipantGroupService {
|
||||||
|
constructor(
|
||||||
|
@InjectModel(ParticipantGroup.name)
|
||||||
|
private readonly participantGroupModel: PaginateModel<ParticipantGroupDocument>,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
async create(data: CreateParticipantGroupDto): Promise<ParticipantGroup> {
|
||||||
|
const participantGroup = new this.participantGroupModel({
|
||||||
|
...data,
|
||||||
|
id: data.id || undefined, // Let BaseEntity generate UUID
|
||||||
|
metadata: data.metadata || { entries: [] },
|
||||||
|
});
|
||||||
|
return participantGroup.save();
|
||||||
|
}
|
||||||
|
|
||||||
|
async findAll(page = 1, limit = 10): Promise<{ // returns non uuid id !!!
|
||||||
|
docs: ParticipantGroup[];
|
||||||
|
totalDocs: number;
|
||||||
|
limit: number;
|
||||||
|
page: number;
|
||||||
|
totalPages: number;
|
||||||
|
hasNextPage: boolean;
|
||||||
|
hasPrevPage: boolean;
|
||||||
|
nextPage: number | null;
|
||||||
|
prevPage: number | null;
|
||||||
|
}> {
|
||||||
|
return this.participantGroupModel.paginate(
|
||||||
|
{},
|
||||||
|
{ page, limit, lean: true },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
async findById(id: string): Promise<ParticipantGroup | null> {
|
||||||
|
return this.participantGroupModel.findOne({ id }).lean().exec();
|
||||||
|
}
|
||||||
|
|
||||||
|
async update(id: string, data: UpdateParticipantGroupDto): Promise<ParticipantGroup | null> {
|
||||||
|
return this.participantGroupModel
|
||||||
|
.findOneAndUpdate(
|
||||||
|
{ id },
|
||||||
|
{ $set: { ...data, updatedAt: new Date() } },
|
||||||
|
{ new: true },
|
||||||
|
).lean().exec();
|
||||||
|
}
|
||||||
|
|
||||||
|
async remove(id: string): Promise<void> {
|
||||||
|
await this.participantGroupModel.deleteOne({ id }).exec();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -4,24 +4,7 @@ import { Model } from 'mongoose';
|
||||||
import { Question, QuestionDocument } from './entity/question.entity';
|
import { Question, QuestionDocument } from './entity/question.entity';
|
||||||
import { CreateQuestionDto } from './dto/create-question.dto';
|
import { CreateQuestionDto } from './dto/create-question.dto';
|
||||||
import { UpdateQuestionDto } from './dto/update-question.dto';
|
import { UpdateQuestionDto } from './dto/update-question.dto';
|
||||||
|
import { PaginateModel } from '../participant/participant.service';
|
||||||
// Interface matching the mongoose-paginate-v2 plugin
|
|
||||||
interface PaginateModel<T> extends Model<T> {
|
|
||||||
paginate: (
|
|
||||||
query?: any,
|
|
||||||
options?: { page: number; limit: number; lean?: boolean; select?: string },
|
|
||||||
) => Promise<{
|
|
||||||
docs: T[];
|
|
||||||
totalDocs: number;
|
|
||||||
limit: number;
|
|
||||||
page: number;
|
|
||||||
totalPages: number;
|
|
||||||
hasNextPage: boolean;
|
|
||||||
hasPrevPage: boolean;
|
|
||||||
nextPage: number | null;
|
|
||||||
prevPage: number | null;
|
|
||||||
}>;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class QuestionService {
|
export class QuestionService {
|
||||||
|
|
@ -54,20 +37,15 @@ export class QuestionService {
|
||||||
prevPage: number | null;
|
prevPage: number | null;
|
||||||
}> {
|
}> {
|
||||||
// Selects all fields from the Question entity for the response
|
// Selects all fields from the Question entity for the response
|
||||||
const selectFields =
|
|
||||||
'id text type isRequired isConfidential validationRules options attachments metadata status createdAt updatedAt';
|
|
||||||
return this.questionModel.paginate(
|
return this.questionModel.paginate(
|
||||||
{},
|
{},
|
||||||
{ page, limit, lean: true, select: selectFields },
|
{ page, limit, lean: true },
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
async findById(id: string): Promise<Question | null> {
|
async findById(id: string): Promise<Question | null> {
|
||||||
const selectFields =
|
|
||||||
'id text type isRequired isConfidential validationRules options attachments metadata status createdAt updatedAt';
|
|
||||||
const question = await this.questionModel
|
const question = await this.questionModel
|
||||||
.findOne({ id })
|
.findOne({ id })
|
||||||
.select(selectFields)
|
|
||||||
.lean()
|
.lean()
|
||||||
.exec();
|
.exec();
|
||||||
if (!question) {
|
if (!question) {
|
||||||
|
|
@ -80,15 +58,12 @@ export class QuestionService {
|
||||||
id: string,
|
id: string,
|
||||||
data: UpdateQuestionDto,
|
data: UpdateQuestionDto,
|
||||||
): Promise<Question | null> {
|
): Promise<Question | null> {
|
||||||
const selectFields =
|
|
||||||
'id text type isRequired isConfidential validationRules options attachments metadata status createdAt updatedAt';
|
|
||||||
const updatedQuestion = await this.questionModel
|
const updatedQuestion = await this.questionModel
|
||||||
.findOneAndUpdate(
|
.findOneAndUpdate(
|
||||||
{ id },
|
{ id },
|
||||||
{ $set: { ...data, updatedAt: new Date() } },
|
{ $set: { ...data, updatedAt: new Date() } },
|
||||||
{ new: true },
|
{ new: true },
|
||||||
)
|
)
|
||||||
.select(selectFields)
|
|
||||||
.lean()
|
.lean()
|
||||||
.exec();
|
.exec();
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue