refactor: populate queries

This commit is contained in:
Mohamed Marrouchi
2024-09-21 12:15:36 +01:00
parent bb52f2a1d5
commit 7bc5270551
67 changed files with 661 additions and 1016 deletions

View File

@@ -36,14 +36,24 @@ import { PopulatePipe } from '@/utils/pipes/populate.pipe';
import { SearchFilterPipe } from '@/utils/pipes/search-filter.pipe';
import { BlockCreateDto, BlockUpdateDto } from '../dto/block.dto';
import { Block, BlockFull, BlockStub } from '../schemas/block.schema';
import {
Block,
BlockFull,
BlockPopulate,
BlockStub,
} from '../schemas/block.schema';
import { BlockService } from '../services/block.service';
import { CategoryService } from '../services/category.service';
import { LabelService } from '../services/label.service';
@UseInterceptors(CsrfInterceptor)
@Controller('Block')
export class BlockController extends BaseController<Block, BlockStub> {
export class BlockController extends BaseController<
Block,
BlockStub,
BlockPopulate,
BlockFull
> {
constructor(
private readonly blockService: BlockService,
private readonly logger: LoggerService,
@@ -68,15 +78,7 @@ export class BlockController extends BaseController<Block, BlockStub> {
@Query(new SearchFilterPipe<Block>({ allowedFields: ['category'] }))
filters: TFilterQuery<Block>,
): Promise<Block[] | BlockFull[]> {
return this.canPopulate(populate, [
'trigger_labels',
'assign_labels',
'nextBlocks',
'attachedBlock',
'category',
'previousBlocks',
'attachedToBlock',
])
return this.canPopulate(populate)
? await this.blockService.findAndPopulate(filters)
: await this.blockService.find(filters);
}
@@ -189,15 +191,7 @@ export class BlockController extends BaseController<Block, BlockStub> {
@Query(PopulatePipe)
populate: string[],
): Promise<Block | BlockFull> {
const doc = this.canPopulate(populate, [
'trigger_labels',
'assign_labels',
'nextBlocks',
'attachedBlock',
'category',
'previousBlocks',
'attachedToBlock',
])
const doc = this.canPopulate(populate)
? await this.blockService.findOneAndPopulate(id)
: await this.blockService.findOne(id);
if (!doc) {

View File

@@ -33,7 +33,6 @@ import { SearchFilterPipe } from '@/utils/pipes/search-filter.pipe';
import { CategoryCreateDto, CategoryUpdateDto } from '../dto/category.dto';
import { Category } from '../schemas/category.schema';
import { BlockService } from '../services/block.service';
import { CategoryService } from '../services/category.service';
@UseInterceptors(CsrfInterceptor)
@@ -41,7 +40,6 @@ import { CategoryService } from '../services/category.service';
export class CategoryController extends BaseController<Category> {
constructor(
private readonly categoryService: CategoryService,
private readonly blockService: BlockService,
private readonly logger: LoggerService,
) {
super(categoryService);

View File

@@ -32,12 +32,22 @@ import { PopulatePipe } from '@/utils/pipes/populate.pipe';
import { SearchFilterPipe } from '@/utils/pipes/search-filter.pipe';
import { LabelCreateDto, LabelUpdateDto } from '../dto/label.dto';
import { Label, LabelStub } from '../schemas/label.schema';
import {
Label,
LabelFull,
LabelPopulate,
LabelStub,
} from '../schemas/label.schema';
import { LabelService } from '../services/label.service';
@UseInterceptors(CsrfInterceptor)
@Controller('label')
export class LabelController extends BaseController<Label, LabelStub> {
export class LabelController extends BaseController<
Label,
LabelStub,
LabelPopulate,
LabelFull
> {
constructor(
private readonly labelService: LabelService,
private readonly logger: LoggerService,
@@ -53,7 +63,7 @@ export class LabelController extends BaseController<Label, LabelStub> {
@Query(new SearchFilterPipe<Label>({ allowedFields: ['name', 'title'] }))
filters: TFilterQuery<Label>,
) {
return this.canPopulate(populate, ['users'])
return this.canPopulate(populate)
? await this.labelService.findPageAndPopulate(filters, pageQuery)
: await this.labelService.findPage(filters, pageQuery);
}
@@ -80,7 +90,7 @@ export class LabelController extends BaseController<Label, LabelStub> {
@Query(PopulatePipe)
populate: string[],
) {
const doc = this.canPopulate(populate, ['users'])
const doc = this.canPopulate(populate)
? await this.labelService.findOneAndPopulate(id)
: await this.labelService.findOne(id);
if (!doc) {

View File

@@ -36,7 +36,12 @@ import { PopulatePipe } from '@/utils/pipes/populate.pipe';
import { SearchFilterPipe } from '@/utils/pipes/search-filter.pipe';
import { MessageCreateDto } from '../dto/message.dto';
import { Message, MessageStub } from '../schemas/message.schema';
import {
Message,
MessageFull,
MessagePopulate,
MessageStub,
} from '../schemas/message.schema';
import {
OutgoingMessage,
OutgoingMessageFormat,
@@ -49,7 +54,12 @@ import { SubscriberService } from '../services/subscriber.service';
@UseInterceptors(CsrfInterceptor)
@Controller('message')
export class MessageController extends BaseController<Message, MessageStub> {
export class MessageController extends BaseController<
Message,
MessageStub,
MessagePopulate,
MessageFull
> {
constructor(
private readonly messageService: MessageService,
private readonly subscriberService: SubscriberService,
@@ -70,7 +80,7 @@ export class MessageController extends BaseController<Message, MessageStub> {
)
filters: TFilterQuery<Message>,
) {
return this.canPopulate(populate, ['recipient', 'sender', 'sentBy'])
return this.canPopulate(populate)
? await this.messageService.findPageAndPopulate(filters, pageQuery)
: await this.messageService.findPage(filters, pageQuery);
}
@@ -97,7 +107,7 @@ export class MessageController extends BaseController<Message, MessageStub> {
@Query(PopulatePipe)
populate: string[],
) {
const doc = this.canPopulate(populate, ['recipient', 'sender', 'sentBy'])
const doc = this.canPopulate(populate)
? await this.messageService.findOneAndPopulate(id)
: await this.messageService.findOne(id);
if (!doc) {

View File

@@ -32,14 +32,21 @@ import { PopulatePipe } from '@/utils/pipes/populate.pipe';
import { SearchFilterPipe } from '@/utils/pipes/search-filter.pipe';
import { SubscriberUpdateDto } from '../dto/subscriber.dto';
import { Subscriber, SubscriberStub } from '../schemas/subscriber.schema';
import {
Subscriber,
SubscriberFull,
SubscriberPopulate,
SubscriberStub,
} from '../schemas/subscriber.schema';
import { SubscriberService } from '../services/subscriber.service';
@UseInterceptors(CsrfInterceptor)
@Controller('subscriber')
export class SubscriberController extends BaseController<
Subscriber,
SubscriberStub
SubscriberStub,
SubscriberPopulate,
SubscriberFull
> {
constructor(
private readonly subscriberService: SubscriberService,
@@ -67,7 +74,7 @@ export class SubscriberController extends BaseController<
)
filters: TFilterQuery<Subscriber>,
) {
return this.canPopulate(populate, ['labels', 'assignedTo', 'avatar'])
return this.canPopulate(populate)
? await this.subscriberService.findPageAndPopulate(filters, pageQuery)
: await this.subscriberService.findPage(filters, pageQuery);
}
@@ -100,7 +107,7 @@ export class SubscriberController extends BaseController<
@Query(PopulatePipe)
populate: string[],
) {
const doc = this.canPopulate(populate, ['labels', 'assignedTo', 'avatar'])
const doc = this.canPopulate(populate)
? await this.subscriberService.findOneAndPopulate(id)
: await this.subscriberService.findOne(id);
if (!doc) {

View File

@@ -10,11 +10,11 @@
import { Injectable, Optional } from '@nestjs/common';
import { InjectModel } from '@nestjs/mongoose';
import {
TFilterQuery,
Model,
Document,
Types,
Model,
Query,
TFilterQuery,
Types,
UpdateQuery,
UpdateWithAggregationPipeline,
} from 'mongoose';
@@ -23,27 +23,24 @@ import { LoggerService } from '@/logger/logger.service';
import { BaseRepository, DeleteResult } from '@/utils/generics/base-repository';
import { BlockCreateDto, BlockUpdateDto } from '../dto/block.dto';
import { Block, BlockFull } from '../schemas/block.schema';
import {
Block,
BLOCK_POPULATE,
BlockFull,
BlockPopulate,
} from '../schemas/block.schema';
@Injectable()
export class BlockRepository extends BaseRepository<
Block,
| 'trigger_labels'
| 'assign_labels'
| 'nextBlocks'
| 'attachedBlock'
| 'category'
| 'previousBlocks'
| 'attachedToBlock'
BlockPopulate,
BlockFull
> {
private readonly logger: LoggerService;
constructor(
@InjectModel(Block.name) readonly model: Model<Block>,
@Optional() logger?: LoggerService,
@Optional() private readonly logger?: LoggerService,
) {
super(model, Block);
this.logger = logger;
super(model, Block, BLOCK_POPULATE, BlockFull);
}
/**
@@ -160,44 +157,4 @@ export class BlockRepository extends BaseRepository<
);
}
}
/**
* Finds blocks and populates related fields (e.g., labels, attached blocks).
*
* @param filters - The filter criteria for finding blocks.
*
* @returns The populated block results.
*/
async findAndPopulate(filters: TFilterQuery<Block>) {
const query = this.findQuery(filters).populate([
'trigger_labels',
'assign_labels',
'nextBlocks',
'attachedBlock',
'category',
'previousBlocks',
'attachedToBlock',
]);
return await this.execute(query, BlockFull);
}
/**
* Finds a single block by ID and populates related fields (e.g., labels, attached blocks).
*
* @param id - The ID of the block to find.
*
* @returns The populated block result or null if not found.
*/
async findOneAndPopulate(id: string) {
const query = this.findOneQuery(id).populate([
'trigger_labels',
'assign_labels',
'nextBlocks',
'attachedBlock',
'category',
'previousBlocks',
'attachedToBlock',
]);
return await this.executeOne(query, BlockFull);
}
}

View File

@@ -16,20 +16,23 @@ import { BaseRepository } from '@/utils/generics/base-repository';
import {
Conversation,
CONVERSATION_POPULATE,
ConversationDocument,
ConversationFull,
ConversationPopulate,
} from '../schemas/conversation.schema';
@Injectable()
export class ConversationRepository extends BaseRepository<
Conversation,
'sender' | 'current' | 'next'
ConversationPopulate,
ConversationFull
> {
constructor(
@InjectModel(Conversation.name) readonly model: Model<Conversation>,
private readonly eventEmitter: EventEmitter2,
) {
super(model, Conversation);
super(model, Conversation, CONVERSATION_POPULATE, ConversationFull);
}
/**

View File

@@ -10,20 +10,26 @@
import { Injectable } from '@nestjs/common';
import { EventEmitter2 } from '@nestjs/event-emitter';
import { InjectModel } from '@nestjs/mongoose';
import { TFilterQuery, Model, Document, Query } from 'mongoose';
import { Document, Model, Query, TFilterQuery } from 'mongoose';
import { LoggerService } from '@/logger/logger.service';
import { BaseRepository, DeleteResult } from '@/utils/generics/base-repository';
import { PageQueryDto } from '@/utils/pagination/pagination-query.dto';
import { Label, LabelDocument, LabelFull } from '../schemas/label.schema';
import {
Label,
LabelDocument,
LabelFull,
LabelPopulate,
} from '../schemas/label.schema';
@Injectable()
export class LabelRepository extends BaseRepository<Label, 'users'> {
export class LabelRepository extends BaseRepository<
Label,
LabelPopulate,
LabelFull
> {
constructor(
@InjectModel(Label.name) readonly model: Model<Label>,
private readonly eventEmitter: EventEmitter2,
private readonly logger: LoggerService,
) {
super(model, Label);
}
@@ -78,42 +84,4 @@ export class LabelRepository extends BaseRepository<Label, 'users'> {
);
this.eventEmitter.emit('hook:chatbot:label:delete', labels);
}
/**
* Fetches all label documents and populates the `users` field which references the subscribers.
*
* @returns A promise that resolves with an array of fully populated `LabelFull` documents.
*/
async findAllAndPopulate() {
const query = this.findAllQuery().populate(['users']);
return await this.execute(query, LabelFull);
}
/**
* Fetches a paginated list of label documents based on filters and populates the `users` (subscribers) field.
*
* @param filters - The filter criteria for querying the labels.
* @param pageQuery - The pagination query options.
*
* @returns A promise that resolves with a paginated array of fully populated `LabelFull` documents.
*/
async findPageAndPopulate(
filters: TFilterQuery<Label>,
pageQuery: PageQueryDto<Label>,
) {
const query = this.findPageQuery(filters, pageQuery).populate(['users']);
return await this.execute(query, LabelFull);
}
/**
* Fetches a single label document by its ID and populates the `users` (subscribers) field.
*
* @param id - The ID of the label to be fetched.
*
* @returns A promise that resolves with a fully populated label.
*/
async findOneAndPopulate(id: string) {
const query = this.findOneQuery(id).populate(['users']);
return await this.executeOne(query, LabelFull);
}
}

View File

@@ -9,23 +9,27 @@
import { Injectable, Optional } from '@nestjs/common';
import { InjectModel } from '@nestjs/mongoose';
import { TFilterQuery, Model, Query } from 'mongoose';
import { Model } from 'mongoose';
import { LoggerService } from '@/logger/logger.service';
import { NlpSampleCreateDto } from '@/nlp/dto/nlp-sample.dto';
import { NlpSampleState } from '@/nlp/schemas/types';
import { NlpSampleService } from '@/nlp/services/nlp-sample.service';
import { BaseRepository } from '@/utils/generics/base-repository';
import { PageQueryDto } from '@/utils/pagination/pagination-query.dto';
import { Message, MessageFull } from '../schemas/message.schema';
import {
Message,
MessageFull,
MessagePopulate,
} from '../schemas/message.schema';
import { Subscriber } from '../schemas/subscriber.schema';
import { AnyMessage } from '../schemas/types/message';
@Injectable()
export class MessageRepository extends BaseRepository<
AnyMessage,
'sender' | 'recipient'
MessagePopulate,
MessageFull
> {
private readonly nlpSampleService: NlpSampleService;
@@ -81,42 +85,6 @@ export class MessageRepository extends BaseRepository<
}
}
/**
* Retrieves a paginated list of messages with sender and recipient populated.
* Uses filter criteria and pagination settings for the query.
*
* @param filters - Filter criteria for querying messages.
* @param pageQuery - Pagination settings, including skip, limit, and sort order.
*
* @returns A paginated list of messages with sender and recipient details populated.
*/
async findPageAndPopulate(
filters: TFilterQuery<AnyMessage>,
pageQuery: PageQueryDto<AnyMessage>,
) {
const query = this.findPageQuery(filters, pageQuery).populate([
'sender',
'recipient',
]);
return await this.execute(
query as Query<AnyMessage[], AnyMessage, object, AnyMessage, 'find'>,
MessageFull,
);
}
/**
* Retrieves a single message by its ID, populating the sender and recipient fields.
*
* @param id - The ID of the message to retrieve.
*
* @returns The message with sender and recipient details populated.
*/
async findOneAndPopulate(id: string) {
const query = this.findOneQuery(id).populate(['sender', 'recipient']);
return await this.executeOne(query, MessageFull);
}
/**
* Retrieves the message history for a given subscriber, with messages sent or received
* before the specified date. Results are limited and sorted by creation date.

View File

@@ -20,19 +20,20 @@ import {
} from 'mongoose';
import { BaseRepository } from '@/utils/generics/base-repository';
import { PageQueryDto } from '@/utils/pagination/pagination-query.dto';
import { SubscriberUpdateDto } from '../dto/subscriber.dto';
import {
Subscriber,
SubscriberDocument,
SubscriberFull,
SubscriberPopulate,
} from '../schemas/subscriber.schema';
@Injectable()
export class SubscriberRepository extends BaseRepository<
Subscriber,
'labels' | 'assignedTo' | 'avatar'
SubscriberPopulate,
SubscriberFull
> {
constructor(
@InjectModel(Subscriber.name) readonly model: Model<Subscriber>,
@@ -159,11 +160,8 @@ export class SubscriberRepository extends BaseRepository<
* @returns The found subscriber entity with populated fields.
*/
async findOneByForeignIdAndPopulate(id: string): Promise<SubscriberFull> {
const query = this.findByForeignIdQuery(id).populate([
'labels',
'assignedTo',
]);
const [result] = await this.execute(query, SubscriberFull);
const query = this.findByForeignIdQuery(id).populate(this.populate);
const [result] = await this.execute(query, this.clsPopulate);
return result;
}
@@ -223,56 +221,4 @@ export class SubscriberRepository extends BaseRepository<
},
);
}
/**
* Finds all subscribers and populates related fields such as `labels`, `assignedTo`, and `avatar`.
*
* @returns A list of all subscribers with populated fields.
*/
async findAllAndPopulate(): Promise<SubscriberFull[]> {
const query = this.findAllQuery().populate([
'labels',
'assignedTo',
'avatar',
]);
return await this.execute(query, SubscriberFull);
}
/**
* Finds subscribers using pagination and populates related fields such as `labels`, `assignedTo`, and `avatar`.
*
* @param filters - The filter criteria to apply when finding subscribers.
* @param pageQuery - The pagination query.
*
* @returns A paginated list of subscribers with populated fields.
*/
async findPageAndPopulate(
filters: TFilterQuery<Subscriber>,
pageQuery: PageQueryDto<Subscriber>,
): Promise<SubscriberFull[]> {
const query = this.findPageQuery(filters, pageQuery).populate([
'labels',
'assignedTo',
'avatar',
]);
return await this.execute(query, SubscriberFull);
}
/**
* Finds a single subscriber by criteria and populates related fields such as `labels`, `assignedTo`, and `avatar`.
*
* @param criteria - The filter criteria to apply when finding a subscriber.
*
* @returns The found subscriber entity with populated fields.
*/
async findOneAndPopulate(
criteria: string | TFilterQuery<Subscriber>,
): Promise<SubscriberFull> {
const query = this.findOneQuery(criteria).populate([
'labels',
'assignedTo',
'avatar',
]);
return await this.executeOne(query, SubscriberFull);
}
}

View File

@@ -13,6 +13,7 @@ import { Schema as MongooseSchema, THydratedDocument } from 'mongoose';
import { BaseSchema } from '@/utils/generics/base-schema';
import { LifecycleHookManager } from '@/utils/generics/lifecycle-hook-manager';
import { TFilterPopulateFields } from '@/utils/types/filter.types';
import { Category } from './category.schema';
import { Label } from './label.schema';
@@ -194,3 +195,15 @@ BlockModel.schema.virtual('attachedToBlock', {
});
export default BlockModel.schema;
export type BlockPopulate = keyof TFilterPopulateFields<Block, BlockStub>;
export const BLOCK_POPULATE: BlockPopulate[] = [
'trigger_labels',
'assign_labels',
'nextBlocks',
'attachedBlock',
'category',
'previousBlocks',
'attachedToBlock',
];

View File

@@ -12,6 +12,7 @@ import { Transform, Type } from 'class-transformer';
import { THydratedDocument, Schema as MongooseSchema } from 'mongoose';
import { BaseSchema } from '@/utils/generics/base-schema';
import { TFilterPopulateFields } from '@/utils/types/filter.types';
import { Block } from './block.schema';
import { Subscriber } from './subscriber.schema';
@@ -103,3 +104,14 @@ export const ConversationModel: ModelDefinition = {
};
export default ConversationModel.schema;
export type ConversationPopulate = keyof TFilterPopulateFields<
Conversation,
ConversationStub
>;
export const CONVERSATION_POPULATE: ConversationPopulate[] = [
'sender',
'current',
'next',
];

View File

@@ -13,6 +13,7 @@ import { THydratedDocument } from 'mongoose';
import { BaseSchema } from '@/utils/generics/base-schema';
import { LifecycleHookManager } from '@/utils/generics/lifecycle-hook-manager';
import { TFilterPopulateFields } from '@/utils/types/filter.types';
import { Subscriber } from './subscriber.schema';
@@ -77,3 +78,7 @@ LabelModel.schema.virtual('users', {
});
export default LabelModel.schema;
export type LabelPopulate = keyof TFilterPopulateFields<Label, LabelStub>;
export const LABEL_POPULATE: LabelPopulate[] = ['users'];

View File

@@ -13,6 +13,7 @@ import { Schema as MongooseSchema } from 'mongoose';
import { BaseSchema } from '@/utils/generics/base-schema';
import { LifecycleHookManager } from '@/utils/generics/lifecycle-hook-manager';
import { TFilterPopulateFields } from '@/utils/types/filter.types';
import { Subscriber } from './subscriber.schema';
import { StdIncomingMessage, StdOutgoingMessage } from './types/message';
@@ -102,3 +103,7 @@ export const MessageModel: ModelDefinition = LifecycleHookManager.attach({
});
export default MessageModel.schema;
export type MessagePopulate = keyof TFilterPopulateFields<Message, MessageStub>;
export const MESSAGE_POPULATE: MessagePopulate[] = ['sender', 'recipient'];

View File

@@ -15,6 +15,7 @@ import { Attachment } from '@/attachment/schemas/attachment.schema';
import { User } from '@/user/schemas/user.schema';
import { BaseSchema } from '@/utils/generics/base-schema';
import { LifecycleHookManager } from '@/utils/generics/lifecycle-hook-manager';
import { TFilterPopulateFields } from '@/utils/types/filter.types';
import { Label } from './label.schema';
import { ChannelData } from './types/channel';
@@ -140,3 +141,14 @@ export const SubscriberModel: ModelDefinition = LifecycleHookManager.attach({
});
export default SubscriberModel.schema;
export type SubscriberPopulate = keyof TFilterPopulateFields<
Subscriber,
SubscriberStub
>;
export const SUBSCRIBER_POPULATE: SubscriberPopulate[] = [
'labels',
'assignedTo',
'avatar',
];

View File

@@ -8,7 +8,6 @@
*/
import { Injectable } from '@nestjs/common';
import { TFilterQuery } from 'mongoose';
import { Attachment } from '@/attachment/schemas/attachment.schema';
import { AttachmentService } from '@/attachment/services/attachment.service';
@@ -24,7 +23,7 @@ import { SettingService } from '@/setting/services/setting.service';
import { BaseService } from '@/utils/generics/base-service';
import { BlockRepository } from '../repositories/block.repository';
import { Block, BlockFull } from '../schemas/block.schema';
import { Block, BlockFull, BlockPopulate } from '../schemas/block.schema';
import { WithUrl } from '../schemas/types/attachment';
import { Context } from '../schemas/types/context';
import {
@@ -36,7 +35,7 @@ import { NlpPattern, Pattern, PayloadPattern } from '../schemas/types/pattern';
import { Payload, StdQuickReply } from '../schemas/types/quick-reply';
@Injectable()
export class BlockService extends BaseService<Block> {
export class BlockService extends BaseService<Block, BlockPopulate, BlockFull> {
constructor(
readonly repository: BlockRepository,
private readonly contentService: ContentService,
@@ -49,28 +48,6 @@ export class BlockService extends BaseService<Block> {
super(repository);
}
/**
* Finds and populates blocks based on the specified filters.
*
* @param filters - Query filters used to specify search criteria for finding blocks.
*
* @returns A promise that resolves to the populated blocks matching the filters.
*/
async findAndPopulate(filters: TFilterQuery<Block>) {
return await this.repository.findAndPopulate(filters);
}
/**
* Finds and populates a block by ID.
*
* @param id - The block ID.
*
* @returns A promise that resolves to the populated block.
*/
async findOneAndPopulate(id: string) {
return await this.repository.findOneAndPopulate(id);
}
/**
* Find a block whose patterns matches the received event
*

View File

@@ -17,12 +17,20 @@ import { BaseService } from '@/utils/generics/base-service';
import { VIEW_MORE_PAYLOAD } from '../helpers/constants';
import { ConversationRepository } from '../repositories/conversation.repository';
import { Block, BlockFull } from '../schemas/block.schema';
import { Conversation, ConversationFull } from '../schemas/conversation.schema';
import {
Conversation,
ConversationFull,
ConversationPopulate,
} from '../schemas/conversation.schema';
import { OutgoingMessageFormat } from '../schemas/types/message';
import { Payload } from '../schemas/types/quick-reply';
@Injectable()
export class ConversationService extends BaseService<Conversation> {
export class ConversationService extends BaseService<
Conversation,
ConversationPopulate,
ConversationFull
> {
constructor(
readonly repository: ConversationRepository,
private readonly logger: LoggerService,

View File

@@ -14,10 +14,10 @@ import { BaseService } from '@/utils/generics/base-service';
import { PageQueryDto } from '@/utils/pagination/pagination-query.dto';
import { LabelRepository } from '../repositories/label.repository';
import { Label } from '../schemas/label.schema';
import { Label, LabelFull, LabelPopulate } from '../schemas/label.schema';
@Injectable()
export class LabelService extends BaseService<Label> {
export class LabelService extends BaseService<Label, LabelPopulate, LabelFull> {
constructor(readonly repository: LabelRepository) {
super(repository);
}

View File

@@ -29,11 +29,16 @@ import { SocketResponse } from '@/websocket/utils/socket-response';
import { WebsocketGateway } from '@/websocket/websocket.gateway';
import { MessageRepository } from '../repositories/message.repository';
import { MessageFull, MessagePopulate } from '../schemas/message.schema';
import { Subscriber } from '../schemas/subscriber.schema';
import { AnyMessage } from '../schemas/types/message';
@Injectable()
export class MessageService extends BaseService<AnyMessage> {
export class MessageService extends BaseService<
AnyMessage,
MessagePopulate,
MessageFull
> {
private readonly logger: LoggerService;
private readonly gateway: WebsocketGateway;

View File

@@ -35,10 +35,18 @@ import { WebsocketGateway } from '@/websocket/websocket.gateway';
import { SubscriberUpdateDto } from '../dto/subscriber.dto';
import { SubscriberRepository } from '../repositories/subscriber.repository';
import { Subscriber } from '../schemas/subscriber.schema';
import {
Subscriber,
SubscriberFull,
SubscriberPopulate,
} from '../schemas/subscriber.schema';
@Injectable()
export class SubscriberService extends BaseService<Subscriber> {
export class SubscriberService extends BaseService<
Subscriber,
SubscriberPopulate,
SubscriberFull
> {
private readonly gateway: WebsocketGateway;
constructor(