diff --git a/src/modules/classification/classification.controller.ts b/src/modules/classification/classification.controller.ts index 6a8cf14..d3a3290 100644 --- a/src/modules/classification/classification.controller.ts +++ b/src/modules/classification/classification.controller.ts @@ -8,7 +8,7 @@ import { Patch, } from '@nestjs/common'; import { ClassificationService } from './classification.service'; -import { GetUser, PaginationQuery } from '@src/common'; +import { GetUser, PaginationMetadata, PaginationQuery } from '@src/common'; import { ClassificationControllerDocs, GetAIFolderNameListDocs, @@ -37,29 +37,40 @@ export class ClassificationController { @GetAIPostListDocs async getSuggestedPostList( @GetUser() userId: string, - @Query() paingQuery: PaginationQuery, + @Query() pagingQuery: PaginationQuery, ) { - const posts = await this.classificationService.getPostList( - userId, - paingQuery, + const { count, classificationPostList } = + await this.classificationService.getPostList(userId, pagingQuery); + + const metadata = new PaginationMetadata( + pagingQuery.page, + pagingQuery.limit, + count, ); - return new AIPostListResponse(posts); + return new AIPostListResponse(metadata, classificationPostList); } @Get('/posts/:folderId') @GetAIPostListDocs async getSuggestedPostListInFolder( @GetUser() userId: string, @Param('folderId') folderId: string, - @Query() paingQuery: PaginationQuery, + @Query() pagingQuery: PaginationQuery, ) { - const posts = await this.classificationService.getPostListInFolder( - userId, - folderId, - paingQuery, + const { count, classificationPostList } = + await this.classificationService.getPostListInFolder( + userId, + folderId, + pagingQuery, + ); + + const metadata = new PaginationMetadata( + pagingQuery.page, + pagingQuery.limit, + count, ); - return new AIPostListResponse(posts); + return new AIPostListResponse(metadata, classificationPostList); } @Patch('/posts') @PatchAIPostDocs diff --git a/src/modules/classification/classification.repository.ts b/src/modules/classification/classification.repository.ts index d3fe524..8fb38bc 100644 --- a/src/modules/classification/classification.repository.ts +++ b/src/modules/classification/classification.repository.ts @@ -11,6 +11,46 @@ export class ClassficiationRepository { private readonly aiClassificationModel: Model, ) {} + async getClassificationPostCount( + userId: string, + suggestedFolderId?: string, + ): Promise { + const result = await this.aiClassificationModel + .aggregate([ + { + $match: { + deletedAt: null, + }, + }, + { + $lookup: { + from: 'posts', + localField: '_id', + foreignField: 'aiClassificationId', + as: 'post', + }, + }, + { + $unwind: '$post', + }, + { + $match: { + 'post.userId': new Types.ObjectId(userId), + ...(suggestedFolderId && { + suggestedFolderId: new Types.ObjectId(suggestedFolderId), + }), + }, + }, + { + $count: 'count', + }, + ]) + .exec(); + + const count = result[0]?.count || 0; + return count; + } + async createClassification( url: string, description: string, diff --git a/src/modules/classification/classification.service.ts b/src/modules/classification/classification.service.ts index 820c2e8..79a209b 100644 --- a/src/modules/classification/classification.service.ts +++ b/src/modules/classification/classification.service.ts @@ -13,7 +13,7 @@ import { ClassificationFolderWithCount, PostListInClassificationFolder, } from './dto/classification.dto'; -import { PaginationQuery } from '@src/common'; +import { PaginationQuery, sum } from '@src/common'; import { PostListInFolderResponse } from '../folders/responses'; @Injectable() @@ -34,41 +34,53 @@ export class ClassificationService { } async getPostList(userId: string, paingQuery: PaginationQuery) { - const orderedFolderIdList = await this.getFolderOrder(userId); + const { count, orderedFolderIdList } = + await this.getFolderCountAndOrder(userId); const offset = (paingQuery.page - 1) * paingQuery.limit; - return await this.postRepository.findAndSortBySuggestedFolderIds( - new Types.ObjectId(userId), - orderedFolderIdList, - offset, - paingQuery.limit, - ); + const classificationPostList = + await this.postRepository.findAndSortBySuggestedFolderIds( + new Types.ObjectId(userId), + orderedFolderIdList, + offset, + paingQuery.limit, + ); + + return { count, classificationPostList }; } - async getFolderOrder(userId: string) { + async getFolderCountAndOrder(userId: string) { const orderedFolderList = await this.classficationRepository.findContainedFolderByUserId( new Types.ObjectId(userId), ); - return orderedFolderList.map( + const count = sum(orderedFolderList, (folder) => folder.postCount); + const orderedFolderIdList = orderedFolderList.map( (folder) => new Types.ObjectId(folder.folderId), ); + + return { count, orderedFolderIdList }; } async getPostListInFolder( userId: string, folderId: string, paingQuery: PaginationQuery, - ): Promise { + ) { const offset = (paingQuery.page - 1) * paingQuery.limit; - return await this.postRepository.findBySuggestedFolderId( - userId, - new Types.ObjectId(folderId), - offset, - paingQuery.limit, - ); + const [count, classificationPostList] = await Promise.all([ + this.classficationRepository.getClassificationPostCount(userId, folderId), + this.postRepository.findBySuggestedFolderId( + userId, + new Types.ObjectId(folderId), + offset, + paingQuery.limit, + ), + ]); + + return { count, classificationPostList }; } async moveAllPostTosuggestionFolder( userId: string, diff --git a/src/modules/classification/dto/classification.dto.ts b/src/modules/classification/dto/classification.dto.ts index bd7a779..a06e384 100644 --- a/src/modules/classification/dto/classification.dto.ts +++ b/src/modules/classification/dto/classification.dto.ts @@ -7,6 +7,8 @@ export interface ClassificationFolderWithCount { export interface PostListInClassificationFolder { postId: string; + folderId: string; + title: string; url: string; diff --git a/src/modules/classification/response/ai-post-list.dto.ts b/src/modules/classification/response/ai-post-list.dto.ts index 998ba7e..7d7adf9 100644 --- a/src/modules/classification/response/ai-post-list.dto.ts +++ b/src/modules/classification/response/ai-post-list.dto.ts @@ -4,14 +4,24 @@ import { ClassificationPostList, PostListInClassificationFolder, } from '../dto/classification.dto'; +import { PaginationMetadata } from '@src/common'; export class AIPostListResponse { + @ApiProperty({ + type: PaginationMetadata, + }) + metadata: PaginationMetadata; + @ApiProperty() list: PostListInClassificationFolder[] | ClassificationPostList[]; constructor( - data: PostListInClassificationFolder[] | ClassificationPostList[], + metaData: PaginationMetadata, + classificationPostList: + | PostListInClassificationFolder[] + | ClassificationPostList[], ) { - this.list = data; + this.metadata = metaData; + this.list = classificationPostList; } } diff --git a/src/modules/posts/posts.repository.ts b/src/modules/posts/posts.repository.ts index 16a4a42..93e69f3 100644 --- a/src/modules/posts/posts.repository.ts +++ b/src/modules/posts/posts.repository.ts @@ -168,13 +168,20 @@ export class PostsRepository { { $project: { _id: 0, + folderId: { $toString: '$aiClassification.suggestedFolderId' }, postId: { $toString: '$_id' }, title: 1, url: 1, description: 1, createdAt: 1, - isRead: 1, - 'aiClassification.keywords': 1, + isRead: { + $cond: { + if: { $eq: ['$readAt', null] }, + then: false, + else: true, + }, + }, + keywords: '$aiClassification.keywords', }, }, ]) @@ -266,8 +273,14 @@ export class PostsRepository { url: 1, description: 1, createdAt: 1, - isRead: 1, - 'aiClassification.keywords': 1, + isRead: { + $cond: { + if: { $eq: ['$readAt', null] }, + then: false, + else: true, + }, + }, + keywords: '$aiClassification.keywords', }, }, ])