From 343dda20071c31e851a90c500926c08c05d4215f Mon Sep 17 00:00:00 2001 From: marknguyen1302 Date: Thu, 8 Aug 2024 16:15:47 +0700 Subject: [PATCH] feat: add pagination for thread --- .../controllers/threads.controller.ts | 9 ++- .../src/usecases/threads/threads.usecases.ts | 66 +++++++++++++++++-- 2 files changed, 69 insertions(+), 6 deletions(-) diff --git a/cortex-js/src/infrastructure/controllers/threads.controller.ts b/cortex-js/src/infrastructure/controllers/threads.controller.ts index 78a013864..dfa47a37d 100644 --- a/cortex-js/src/infrastructure/controllers/threads.controller.ts +++ b/cortex-js/src/infrastructure/controllers/threads.controller.ts @@ -44,8 +44,13 @@ export class ThreadsController { 'Lists all the available threads along with its configurations.', }) @Get() - findAll() { - return this.threadsUsecases.findAll(); + findAll( + @Query('limit', new DefaultValuePipe(20)) limit: number, + @Query('order', new DefaultValuePipe('desc')) order: 'asc' | 'desc', + @Query('after') after?: string, + @Query('before') before?: string, + ) { + return this.threadsUsecases.findAll(limit, order, after, before); } @ApiOperation({ diff --git a/cortex-js/src/usecases/threads/threads.usecases.ts b/cortex-js/src/usecases/threads/threads.usecases.ts index 7791b955e..46c38bea2 100644 --- a/cortex-js/src/usecases/threads/threads.usecases.ts +++ b/cortex-js/src/usecases/threads/threads.usecases.ts @@ -51,11 +51,69 @@ export class ThreadsUsecases { return this.threadRepository.create(thread); } - async findAll(): Promise { - return this.threadRepository.findAll({ - include: [{ all: true }], - order: [['created_at', 'DESC']], + async findAll( + limit: number, + order: 'asc' | 'desc', + after?: string, + before?: string, + ): Promise> { + const normalizedOrder = order === 'asc' ? 'ASC' : 'DESC'; + let afterQuery = {}; + let beforeQuery = {}; + if (after) { + const [afterDate, afterId] = after.split('_'); + const operator = order === 'asc' ? Op.gt : Op.lt; + afterQuery = { + [Op.or]: [ + { + created_at: { [operator]: Number(afterDate) }, + }, + { + created_at: Number(afterDate), + id: { [operator]: afterId }, + }, + ], + }; + } + if (before) { + const [beforeDate, beforeId] = before.split('_'); + const operator = order === 'asc' ? Op.lt : Op.gt; + beforeQuery = { + [Op.or]: [ + { + created_at: { [operator]: Number(beforeDate) }, + }, + { + created_at: Number(beforeDate), + id: { [operator]: beforeId }, + }, + ], + }; + } + const threads = await this.threadRepository.findAll({ + order: [ + ['created_at', normalizedOrder], + ['id', normalizedOrder], + ], + limit: limit + 1, + where: { + [Op.and]: [afterQuery, beforeQuery], + }, }); + let hasMore = false; + if (threads.length > limit) { + hasMore = true; + threads.pop(); + } + const firstItem = threads[0]; + const lastItem = threads[threads.length - 1]; + const firstId = firstItem + ? `${firstItem.created_at}_${firstItem.id}` + : undefined; + const lastId = lastItem + ? `${lastItem?.created_at}_${lastItem?.id}` + : undefined; + return new PageDto(threads, hasMore, firstId, lastId); } async getMessagesOfThread(