78 أسطر
2.5 KiB
TypeScript
78 أسطر
2.5 KiB
TypeScript
import { Injectable } from '@nestjs/common';
|
|
import { InjectModel } from '@nestjs/mongoose';
|
|
import { ClientSession, FilterQuery, Model, Types } from 'mongoose';
|
|
import { Comment, CommentDocument } from './schemas/comment.schema';
|
|
|
|
@Injectable()
|
|
export class CommentsRepository {
|
|
constructor(@InjectModel(Comment.name) private readonly commentModel: Model<CommentDocument>) {}
|
|
|
|
private withActiveFilter<T extends FilterQuery<CommentDocument>>(filter: T): FilterQuery<CommentDocument> {
|
|
return {
|
|
...filter,
|
|
isDeleted: { $ne: true },
|
|
};
|
|
}
|
|
|
|
async create(
|
|
payload: { postId: string; authorId: string; content: string; parentCommentId?: string },
|
|
session?: ClientSession,
|
|
) {
|
|
return this.commentModel.create({
|
|
postId: new Types.ObjectId(payload.postId),
|
|
authorId: new Types.ObjectId(payload.authorId),
|
|
content: payload.content,
|
|
...(payload.parentCommentId ? { parentCommentId: new Types.ObjectId(payload.parentCommentId) } : {}),
|
|
}, { session });
|
|
}
|
|
|
|
async findById(commentId: string): Promise<CommentDocument | null> {
|
|
if (!Types.ObjectId.isValid(commentId)) {
|
|
return null;
|
|
}
|
|
|
|
return this.commentModel
|
|
.findOne({ _id: new Types.ObjectId(commentId), isDeleted: { $ne: true } })
|
|
.exec();
|
|
}
|
|
|
|
async deleteById(commentId: string, deletedBy?: string, session?: ClientSession): Promise<boolean> {
|
|
if (!Types.ObjectId.isValid(commentId)) {
|
|
return false;
|
|
}
|
|
|
|
const deletedByObjectId =
|
|
deletedBy && Types.ObjectId.isValid(deletedBy) ? new Types.ObjectId(deletedBy) : null;
|
|
|
|
const updated = await this.commentModel
|
|
.findOneAndUpdate(
|
|
{ _id: new Types.ObjectId(commentId), isDeleted: { $ne: true } },
|
|
{ isDeleted: true, deletedAt: new Date(), deletedBy: deletedByObjectId },
|
|
{ new: false, session },
|
|
)
|
|
.exec();
|
|
|
|
return !!updated;
|
|
}
|
|
|
|
async findMany(filter: FilterQuery<CommentDocument>, skip: number, limit: number) {
|
|
return this.commentModel
|
|
.find(this.withActiveFilter(filter))
|
|
.populate({ path: 'authorId', select: 'name username avatar stageName isVerified' })
|
|
.sort({ createdAt: -1 })
|
|
.skip(skip)
|
|
.limit(limit)
|
|
.exec();
|
|
}
|
|
|
|
async count(filter: FilterQuery<CommentDocument>): Promise<number> {
|
|
return this.commentModel.countDocuments(this.withActiveFilter(filter)).exec();
|
|
}
|
|
|
|
async countByPost(postId: string): Promise<number> {
|
|
return this.commentModel
|
|
.countDocuments({ postId: new Types.ObjectId(postId), isDeleted: { $ne: true } })
|
|
.exec();
|
|
}
|
|
}
|