fix(chat): thread query returned OLDEST 300, hiding new messages past the cap

THE disappearing-messages root cause (found via THREAD.length=300 vs 351 on server).
messages.thread and threadByConversation did 'ORDER BY created_at ASC LIMIT 300' —
the oldest 300. Once a DM/group passed 300 messages, every newer message was silently
dropped from the fetch, so anything sent after that point 'disappeared' (persisted
server-side, never returned to the client). Now: inner 'ORDER BY created_at DESC LIMIT'
takes the NEWEST N, outer ASC presents them oldest-first. Cap raised 300 -> 500.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-07 15:08:38 +05:30
parent 507489ec55
commit 4fd323fff4
+12 -6
View File
@@ -204,11 +204,15 @@ const messages = {
attachmentsForDm: (teamId, a, b) => db.prepare(`SELECT at.id, at.name, at.mime, at.size, m.created_at FROM messages m JOIN attachments at ON at.id=m.attachment_id WHERE m.team_id=? AND m.conversation_id IS NULL AND ((m.sender_id=? AND m.recipient_id=?) OR (m.sender_id=? AND m.recipient_id=?)) AND m.deleted=0 ORDER BY m.created_at DESC`).all(teamId, a, b, b, a), attachmentsForDm: (teamId, a, b) => db.prepare(`SELECT at.id, at.name, at.mime, at.size, m.created_at FROM messages m JOIN attachments at ON at.id=m.attachment_id WHERE m.team_id=? AND m.conversation_id IS NULL AND ((m.sender_id=? AND m.recipient_id=?) OR (m.sender_id=? AND m.recipient_id=?)) AND m.deleted=0 ORDER BY m.created_at DESC`).all(teamId, a, b, b, a),
linksForConversation: (teamId, conversationId) => db.prepare("SELECT body, created_at FROM messages WHERE team_id=? AND conversation_id=? AND deleted=0 AND body LIKE '%http%' ORDER BY created_at DESC").all(teamId, conversationId), linksForConversation: (teamId, conversationId) => db.prepare("SELECT body, created_at FROM messages WHERE team_id=? AND conversation_id=? AND deleted=0 AND body LIKE '%http%' ORDER BY created_at DESC").all(teamId, conversationId),
linksForDm: (teamId, a, b) => db.prepare("SELECT body, created_at FROM messages WHERE team_id=? AND conversation_id IS NULL AND ((sender_id=? AND recipient_id=?) OR (sender_id=? AND recipient_id=?)) AND deleted=0 AND body LIKE '%http%' ORDER BY created_at DESC").all(teamId, a, b, b, a), linksForDm: (teamId, a, b) => db.prepare("SELECT body, created_at FROM messages WHERE team_id=? AND conversation_id IS NULL AND ((sender_id=? AND recipient_id=?) OR (sender_id=? AND recipient_id=?)) AND deleted=0 AND body LIKE '%http%' ORDER BY created_at DESC").all(teamId, a, b, b, a),
// Full 1:1 (DM) thread between two users (both directions), oldest first. // Full 1:1 (DM) thread between two users (both directions). Take the NEWEST `limit` messages
thread: (teamId, a, b, limit = 300) => // (inner DESC), then present them oldest-first. The old plain "ASC LIMIT" returned the OLDEST 300
db.prepare(`SELECT * FROM messages WHERE team_id=? AND conversation_id IS NULL // and silently dropped everything newer once a thread passed 300 — so new messages "disappeared".
thread: (teamId, a, b, limit = 500) =>
db.prepare(`SELECT * FROM (
SELECT * FROM messages WHERE team_id=? AND conversation_id IS NULL
AND ((sender_id=? AND recipient_id=?) OR (sender_id=? AND recipient_id=?)) AND ((sender_id=? AND recipient_id=?) OR (sender_id=? AND recipient_id=?))
ORDER BY created_at ASC LIMIT ?`).all(teamId, a, b, b, a, limit), ORDER BY created_at DESC LIMIT ?
) ORDER BY created_at ASC`).all(teamId, a, b, b, a, limit),
markRead: (teamId, recipientId, senderId) => markRead: (teamId, recipientId, senderId) =>
db.prepare('UPDATE messages SET read_at=? WHERE team_id=? AND conversation_id IS NULL AND recipient_id=? AND sender_id=? AND read_at IS NULL') db.prepare('UPDATE messages SET read_at=? WHERE team_id=? AND conversation_id IS NULL AND recipient_id=? AND sender_id=? AND read_at IS NULL')
.run(now(), teamId, recipientId, senderId), .run(now(), teamId, recipientId, senderId),
@@ -217,8 +221,10 @@ const messages = {
db.prepare('SELECT * FROM messages WHERE team_id=? AND conversation_id IS NULL AND (sender_id=? OR recipient_id=?) ORDER BY created_at DESC LIMIT ?') db.prepare('SELECT * FROM messages WHERE team_id=? AND conversation_id IS NULL AND (sender_id=? OR recipient_id=?) ORDER BY created_at DESC LIMIT ?')
.all(teamId, userId, userId, limit), .all(teamId, userId, userId, limit),
// Group conversation helpers. // Group conversation helpers.
threadByConversation: (conversationId, limit = 300) => threadByConversation: (conversationId, limit = 500) =>
db.prepare('SELECT * FROM messages WHERE conversation_id=? ORDER BY created_at ASC LIMIT ?').all(conversationId, limit), db.prepare(`SELECT * FROM (
SELECT * FROM messages WHERE conversation_id=? ORDER BY created_at DESC LIMIT ?
) ORDER BY created_at ASC`).all(conversationId, limit),
lastInConversation: (conversationId) => lastInConversation: (conversationId) =>
db.prepare('SELECT * FROM messages WHERE conversation_id=? ORDER BY created_at DESC LIMIT 1').get(conversationId), db.prepare('SELECT * FROM messages WHERE conversation_id=? ORDER BY created_at DESC LIMIT 1').get(conversationId),
unreadInConversation: (conversationId, userId, since) => unreadInConversation: (conversationId, userId, since) =>