realm done

This commit is contained in:
OkaykOrhmn 2025-07-14 10:58:19 +03:30
parent f17cd3c0f7
commit e568242fdc
6 changed files with 239 additions and 0 deletions

View File

@ -0,0 +1,32 @@
import { IsString, IsOptional, IsUUID, ValidateNested, IsArray, IsEnum, IsDateString } from 'class-validator';
import { Type } from 'class-transformer';
import { BaseDto } from '../../_core/dto/base.dto';
import { CreateAttachmentDto } from '../../attachment/dto/create_attachment.dto';
import { CreateQuestionDto } from '../../question/dto/create-question.dto';
import { CreateFormPageDto } from '../../formPage/dto/create-formPage.dto';
import { CreateParticipantDto } from '../../participant/dto/create-participant.dto';
import { CreateFormDto } from '../../form/dto/create-form.dto';
export class CreateRealmDto extends BaseDto {
@IsString()
title: string;
@IsString()
description: string;
@IsArray()
@ValidateNested({ each: true })
@Type(() => CreateFormDto)
@IsOptional()
forms?: CreateFormDto[];
@IsArray()
@ValidateNested({ each: true })
@Type(() => CreateParticipantDto)
participant: CreateParticipantDto[];
@IsArray()
@ValidateNested({ each: true })
@Type(() => CreateParticipantDto)
owner: CreateParticipantDto;
}

View File

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

View File

@ -0,0 +1,58 @@
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 { Form, FormSchema } from '../../form/entity/form.entity';
import { Participant, ParticipantSchema } from '../../participant/entity/participant.entity';
@Schema({ _id: false, id: false }) // Disable _id and virtual id
export class Realm extends BaseEntity {
@Prop({
type: String,
required: true,
})
title: string;
@Prop({
type: String,
required: true,
})
description: string;
@Prop({
type: [FormSchema],
default: [],
})
forms: Form[];
@Prop({
type: [ParticipantSchema],
default: [],
})
participants: Participant[];
@Prop({
type: ParticipantSchema,
})
owner: Participant;
}
export type RealmDocument = Realm & Document;
export const RealmSchema = SchemaFactory.createForClass(Realm);
RealmSchema.plugin(mongoosePaginate);
// Transform the output to remove the internal '_id'
RealmSchema.set('toJSON', {
transform: (doc: RealmDocument, ret: Realm & { _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 { RealmService } from './realm.service';
import { CreateRealmDto } from './dto/create-realm.dto';
import { UpdateRealmDto } from './dto/update-realm.dto';
import { Realm } from './entity/realm.entity';
@Controller('realms')
export class RealmController {
constructor(private readonly realmService: RealmService) {}
@Post()
@UsePipes(new ValidationPipe({ transform: true, whitelist: true }))
async create(@Body() body: CreateRealmDto): Promise<Realm> {
return this.realmService.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.realmService.findAll(parseInt(page, 10), parseInt(limit, 10));
}
@Get(':id')
async findOne(
@Param('id', new ParseUUIDPipe()) id: string,
): Promise<Realm | null> {
return this.realmService.findById(id);
}
@Patch(':id')
@UsePipes(new ValidationPipe({ transform: true, whitelist: true }))
async update(
@Param('id', new ParseUUIDPipe()) id: string,
@Body() body: UpdateRealmDto,
): Promise<Realm | null> {
return this.realmService.update(id, body);
}
@Delete(':id')
@HttpCode(HttpStatus.NO_CONTENT)
async remove(@Param('id', new ParseUUIDPipe()) id: string): Promise<void> {
return this.realmService.remove(id);
}
}

16
src/realm/realm.module.ts Normal file
View File

@ -0,0 +1,16 @@
import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';
import { RealmService } from './realm.service';
import { RealmController } from './realm.controller';
import { Realm, RealmSchema } from './entity/realm.entity';
@Module({
imports: [
MongooseModule.forFeature([
{ name: Realm.name, schema: RealmSchema },
]),
],
controllers: [RealmController],
providers: [RealmService],
})
export class RealmModule {}

View File

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