🔧 fix: Sorting and Pagination logic for Conversations (#11242)

- Changed default sorting from 'createdAt' to 'updatedAt' in both Conversation and Message routes.
- Updated pagination logic to ensure the cursor is created from the last returned item instead of the popped item, preventing skipped items at page boundaries.
- Added comprehensive tests for pagination behavior, ensuring no messages or conversations are skipped and that sorting works as expected.
This commit is contained in:
Danny Avila 2026-01-07 09:44:45 -05:00 committed by GitHub
parent a95fccc5f3
commit 9434d4a070
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 602 additions and 9 deletions

View file

@ -32,7 +32,7 @@ router.get('/', async (req, res) => {
const cursor = req.query.cursor;
const isArchived = isEnabled(req.query.isArchived);
const search = req.query.search ? decodeURIComponent(req.query.search) : undefined;
const sortBy = req.query.sortBy || 'createdAt';
const sortBy = req.query.sortBy || 'updatedAt';
const sortDirection = req.query.sortDirection || 'desc';
let tags;

View file

@ -24,7 +24,7 @@ router.get('/', async (req, res) => {
const user = req.user.id ?? '';
const {
cursor = null,
sortBy = 'createdAt',
sortBy = 'updatedAt',
sortDirection = 'desc',
pageSize: pageSizeRaw,
conversationId,
@ -55,7 +55,12 @@ router.get('/', async (req, res) => {
.sort({ [sortField]: sortOrder })
.limit(pageSize + 1)
.lean();
const nextCursor = messages.length > pageSize ? messages.pop()[sortField] : null;
let nextCursor = null;
if (messages.length > pageSize) {
messages.pop(); // Remove extra item used to detect next page
// Create cursor from the last RETURNED item (not the popped one)
nextCursor = messages[messages.length - 1][sortField];
}
response = { messages, nextCursor };
} else if (search) {
const searchResults = await Message.meiliSearch(search, { filter: `user = "${user}"` }, true);