diff --git a/server/repos.js b/server/repos.js index baf2195..319f31f 100644 --- a/server/repos.js +++ b/server/repos.js @@ -213,13 +213,17 @@ const messages = { // Full 1:1 (DM) thread between two users (both directions). Take the NEWEST `limit` messages // (inner DESC), then present them oldest-first. The old plain "ASC LIMIT" returned the OLDEST 300 // and silently dropped everything newer once a thread passed 300 — so new messages "disappeared". - thread: (teamId, a, b, limit = 500, before = null) => - db.prepare(`SELECT * FROM ( + // The `before` cursor is added CONDITIONALLY (not as `? IS NULL OR …`): an all-NULL param has no type + // for Postgres to infer. The subquery also needs an alias (`t`) — Postgres requires it. Both portable. + thread: (teamId, a, b, limit = 500, before = null) => { + const cond = before != null ? ' AND created_at < ?' : ''; + const args = before != null ? [teamId, a, b, b, a, before, limit] : [teamId, a, b, b, a, limit]; + return 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 (? IS NULL OR created_at < ?) + AND ((sender_id=? AND recipient_id=?) OR (sender_id=? AND recipient_id=?))${cond} ORDER BY created_at DESC LIMIT ? - ) ORDER BY created_at ASC`).all(teamId, a, b, b, a, before, before, limit), + ) t ORDER BY created_at ASC`).all(...args); + }, // Full-thread search (ALL messages, not just the loaded window). `like` is the escaped LIKE pattern. searchThread: (teamId, a, b, like, limit = 300) => db.prepare(`SELECT id, created_at, sender_id FROM messages WHERE team_id=? AND conversation_id IS NULL @@ -233,10 +237,13 @@ 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 ?') .all(teamId, userId, userId, limit), // Group conversation helpers. - threadByConversation: (conversationId, limit = 500, before = null) => - db.prepare(`SELECT * FROM ( - SELECT * FROM messages WHERE conversation_id=? AND (? IS NULL OR created_at < ?) ORDER BY created_at DESC LIMIT ? - ) ORDER BY created_at ASC`).all(conversationId, before, before, limit), + threadByConversation: (conversationId, limit = 500, before = null) => { + const cond = before != null ? ' AND created_at < ?' : ''; + const args = before != null ? [conversationId, before, limit] : [conversationId, limit]; + return db.prepare(`SELECT * FROM ( + SELECT * FROM messages WHERE conversation_id=?${cond} ORDER BY created_at DESC LIMIT ? + ) t ORDER BY created_at ASC`).all(...args); + }, searchConversation: (conversationId, like, limit = 300) => db.prepare(`SELECT id, created_at, sender_id FROM messages WHERE conversation_id=? AND deleted=0 AND body LIKE ? ESCAPE '\\' ORDER BY created_at ASC LIMIT ?`).all(conversationId, like, limit),