feat: implement dynamic create DTO in the BaseSeeder

This commit is contained in:
yassinedorbozgithub 2025-01-10 12:02:54 +01:00
parent ffc260bba2
commit 21b2f46f4c
10 changed files with 59 additions and 16 deletions

View File

@ -148,6 +148,6 @@ export class BlockUpdateDto extends PartialType(
trigger_channels?: string[]; trigger_channels?: string[];
} }
export type BlockDTOMap = DtoConfig<{ export type BlockDTOMapActions = DtoConfig<{
create: BlockCreateDto; create: BlockCreateDto;
}>; }>;

View File

@ -9,6 +9,8 @@
import { ApiProperty, PartialType } from '@nestjs/swagger'; import { ApiProperty, PartialType } from '@nestjs/swagger';
import { IsBoolean, IsNotEmpty, IsOptional, IsString } from 'class-validator'; import { IsBoolean, IsNotEmpty, IsOptional, IsString } from 'class-validator';
import { DtoConfig } from '@/utils/types/dto.types';
export class ContextVarCreateDto { export class ContextVarCreateDto {
@ApiProperty({ description: 'Context var label', type: String }) @ApiProperty({ description: 'Context var label', type: String })
@IsNotEmpty() @IsNotEmpty()
@ -27,3 +29,7 @@ export class ContextVarCreateDto {
} }
export class ContextVarUpdateDto extends PartialType(ContextVarCreateDto) {} export class ContextVarUpdateDto extends PartialType(ContextVarCreateDto) {}
export type ContextVarDTOMapActions = DtoConfig<{
create: ContextVarCreateDto;
}>;

View File

@ -22,7 +22,11 @@ import { LoggerService } from '@/logger/logger.service';
import { BaseRepository, DeleteResult } from '@/utils/generics/base-repository'; import { BaseRepository, DeleteResult } from '@/utils/generics/base-repository';
import { TFilterQuery } from '@/utils/types/filter.types'; import { TFilterQuery } from '@/utils/types/filter.types';
import { BlockCreateDto, BlockDTOMap, BlockUpdateDto } from '../dto/block.dto'; import {
BlockCreateDto,
BlockDTOMapActions,
BlockUpdateDto,
} from '../dto/block.dto';
import { import {
Block, Block,
BLOCK_POPULATE, BLOCK_POPULATE,
@ -35,7 +39,7 @@ export class BlockRepository extends BaseRepository<
Block, Block,
BlockPopulate, BlockPopulate,
BlockFull, BlockFull,
BlockDTOMap BlockDTOMapActions
> { > {
constructor( constructor(
readonly eventEmitter: EventEmitter2, readonly eventEmitter: EventEmitter2,

View File

@ -19,11 +19,17 @@ import { Document, Model, Query } from 'mongoose';
import { BaseRepository, DeleteResult } from '@/utils/generics/base-repository'; import { BaseRepository, DeleteResult } from '@/utils/generics/base-repository';
import { TFilterQuery } from '@/utils/types/filter.types'; import { TFilterQuery } from '@/utils/types/filter.types';
import { ContextVarDTOMapActions } from '../dto/context-var.dto';
import { ContextVar } from '../schemas/context-var.schema'; import { ContextVar } from '../schemas/context-var.schema';
import { BlockService } from '../services/block.service'; import { BlockService } from '../services/block.service';
@Injectable() @Injectable()
export class ContextVarRepository extends BaseRepository<ContextVar> { export class ContextVarRepository extends BaseRepository<
ContextVar,
never,
never,
ContextVarDTOMapActions
> {
private readonly blockService: BlockService; private readonly blockService: BlockService;
constructor( constructor(

View File

@ -38,7 +38,7 @@ export class ContextVar extends BaseSchema {
type: Boolean, type: Boolean,
default: false, default: false,
}) })
permanent?: boolean; permanent: boolean;
} }
export const ContextVarModel: ModelDefinition = LifecycleHookManager.attach({ export const ContextVarModel: ModelDefinition = LifecycleHookManager.attach({

View File

@ -10,11 +10,17 @@ import { Injectable } from '@nestjs/common';
import { BaseSeeder } from '@/utils/generics/base-seeder'; import { BaseSeeder } from '@/utils/generics/base-seeder';
import { ContextVarDTOMapActions } from '../dto/context-var.dto';
import { ContextVarRepository } from '../repositories/context-var.repository'; import { ContextVarRepository } from '../repositories/context-var.repository';
import { ContextVar } from '../schemas/context-var.schema'; import { ContextVar } from '../schemas/context-var.schema';
@Injectable() @Injectable()
export class ContextVarSeeder extends BaseSeeder<ContextVar> { export class ContextVarSeeder extends BaseSeeder<
ContextVar,
never,
never,
ContextVarDTOMapActions
> {
constructor(private readonly contextVarRepository: ContextVarRepository) { constructor(private readonly contextVarRepository: ContextVarRepository) {
super(contextVarRepository); super(contextVarRepository);
} }

View File

@ -22,7 +22,7 @@ import { SettingService } from '@/setting/services/setting.service';
import { BaseService } from '@/utils/generics/base-service'; import { BaseService } from '@/utils/generics/base-service';
import { getRandom } from '@/utils/helpers/safeRandom'; import { getRandom } from '@/utils/helpers/safeRandom';
import { BlockDTOMap } from '../dto/block.dto'; import { BlockDTOMapActions } from '../dto/block.dto';
import { BlockRepository } from '../repositories/block.repository'; import { BlockRepository } from '../repositories/block.repository';
import { Block, BlockFull, BlockPopulate } from '../schemas/block.schema'; import { Block, BlockFull, BlockPopulate } from '../schemas/block.schema';
import { Context } from '../schemas/types/context'; import { Context } from '../schemas/types/context';
@ -40,7 +40,7 @@ export class BlockService extends BaseService<
Block, Block,
BlockPopulate, BlockPopulate,
BlockFull, BlockFull,
BlockDTOMap BlockDTOMapActions
> { > {
constructor( constructor(
readonly repository: BlockRepository, readonly repository: BlockRepository,

View File

@ -10,12 +10,18 @@ import { Injectable } from '@nestjs/common';
import { BaseService } from '@/utils/generics/base-service'; import { BaseService } from '@/utils/generics/base-service';
import { ContextVarDTOMapActions } from '../dto/context-var.dto';
import { ContextVarRepository } from '../repositories/context-var.repository'; import { ContextVarRepository } from '../repositories/context-var.repository';
import { Block, BlockFull } from '../schemas/block.schema'; import { Block, BlockFull } from '../schemas/block.schema';
import { ContextVar } from '../schemas/context-var.schema'; import { ContextVar } from '../schemas/context-var.schema';
@Injectable() @Injectable()
export class ContextVarService extends BaseService<ContextVar> { export class ContextVarService extends BaseService<
ContextVar,
never,
never,
ContextVarDTOMapActions
> {
constructor(readonly repository: ContextVarRepository) { constructor(readonly repository: ContextVarRepository) {
super(repository); super(repository);
} }

View File

@ -8,6 +8,8 @@
import { FlattenMaps } from 'mongoose'; import { FlattenMaps } from 'mongoose';
import { DtoActions, DtoInfer, DtoProps } from '../types/dto.types';
import { BaseRepository } from './base-repository'; import { BaseRepository } from './base-repository';
import { BaseSchema } from './base-schema'; import { BaseSchema } from './base-schema';
@ -15,6 +17,7 @@ export abstract class BaseSeeder<
T extends FlattenMaps<unknown>, T extends FlattenMaps<unknown>,
P extends string = never, P extends string = never,
TFull extends Omit<T, P> = never, TFull extends Omit<T, P> = never,
DTOCruds extends DtoProps<any> = unknown,
> { > {
constructor(protected readonly repository: BaseRepository<T, P, TFull>) {} constructor(protected readonly repository: BaseRepository<T, P, TFull>) {}
@ -27,7 +30,9 @@ export abstract class BaseSeeder<
return count === 0; return count === 0;
} }
async seed(models: Omit<T, keyof BaseSchema>[]): Promise<boolean> { async seed<D extends Omit<T, keyof BaseSchema>>(
models: DtoInfer<DtoActions.Create, DTOCruds, D>[],
): Promise<boolean> {
if (await this.isEmpty()) { if (await this.isEmpty()) {
await this.repository.createMany(models); await this.repository.createMany(models);
return true; return true;

View File

@ -8,26 +8,36 @@
import mongoose from 'mongoose'; import mongoose from 'mongoose';
import { ContextVarCreateDto } from '@/chat/dto/context-var.dto'; import { ContextVar, ContextVarModel } from '@/chat/schemas/context-var.schema';
import { ContextVarModel, ContextVar } from '@/chat/schemas/context-var.schema'; import { BaseSchema } from '@/utils/generics/base-schema';
import { getFixturesWithDefaultValues } from '../defaultValues'; import { getFixturesWithDefaultValues } from '../defaultValues';
const contextVars: ContextVarCreateDto[] = [ export const fieldsWithDefaultValues = {
permanent: false,
} satisfies Partial<ContextVar>;
type TFieldWithDefaultValues =
| keyof typeof fieldsWithDefaultValues
| keyof BaseSchema;
type TTransformedField<T> = Omit<T, TFieldWithDefaultValues> &
Partial<Pick<ContextVar, TFieldWithDefaultValues>>;
type TContextVar = TTransformedField<ContextVar>;
const contextVars: TContextVar[] = [
{ {
label: 'test context var 1', label: 'test context var 1',
name: 'test1', name: 'test1',
permanent: false,
}, },
{ {
label: 'test context var 2', label: 'test context var 2',
name: 'test2', name: 'test2',
permanent: false,
}, },
]; ];
export const contextVarFixtures = getFixturesWithDefaultValues<ContextVar>({ export const contextVarFixtures = getFixturesWithDefaultValues<TContextVar>({
fixtures: contextVars, fixtures: contextVars,
defaultValues: fieldsWithDefaultValues,
}); });
export const installContextVarFixtures = async () => { export const installContextVarFixtures = async () => {