-
Notifications
You must be signed in to change notification settings - Fork 3.5k
Preserve alias casing in chat fetch query #1696
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
…liases (update missing mappings)
Reviewer's GuideThis PR standardizes column alias casing in the Entity relationship diagram for quoted SQL aliases in chat fetcherDiagram
CONTACT {
STRING contactId
STRING remoteJid
STRING pushName
STRING profilePicUrl
DATE updatedAt
DATE windowStart
DATE windowExpires
BOOLEAN windowActive
NUMBER unreadMessages
}
MESSAGE {
STRING id
OBJECT key
STRING pushName
STRING participant
STRING messageType
STRING message
OBJECT contextInfo
STRING source
DATE messageTimestamp
STRING instanceId
STRING sessionId
STRING status
}
CONTACT ||--o{ MESSAGE : has_lastMessage
Class diagram for updated chat fetch result mappingclassDiagram
class ContactResult {
+String contactId
+String remoteJid
+String pushName
+String profilePicUrl
+Date updatedAt
+Date windowStart
+Date windowExpires
+Boolean windowActive
+Number unreadMessages
+LastMessage lastMessage
+Number unreadCount
+Boolean isSaved
}
class LastMessage {
+String id
+Object key
+String pushName
+String participant
+String messageType
+String message
+Object contextInfo
+String source
+Date messageTimestamp
+String instanceId
+String sessionId
+String status
}
ContactResult --> LastMessage : lastMessage
File-Level Changes
Possibly linked issues
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const mappedResults = results.map((contact) => { | ||
const lastMessage = contact.lastmessageid | ||
const lastMessage = contact.lastMessageId | ||
? { | ||
id: contact.lastmessageid, | ||
key: contact.lastmessage_key, | ||
pushName: contact.lastmessagepushname, | ||
participant: contact.lastmessageparticipant, | ||
messageType: contact.lastmessagemessagetype, | ||
message: contact.lastmessagemessage, | ||
contextInfo: contact.lastmessagecontextinfo, | ||
source: contact.lastmessagesource, | ||
messageTimestamp: contact.lastmessagemessagetimestamp, | ||
instanceId: contact.lastmessageinstanceid, | ||
sessionId: contact.lastmessagesessionid, | ||
status: contact.lastmessagestatus, | ||
id: contact.lastMessageId, | ||
key: contact.lastMessage_key, | ||
pushName: contact.lastMessagePushName, | ||
participant: contact.lastMessageParticipant, | ||
messageType: contact.lastMessageMessageType, | ||
message: contact.lastMessageMessage, | ||
contextInfo: contact.lastMessageContextInfo, | ||
source: contact.lastMessageSource, | ||
messageTimestamp: contact.lastMessageMessageTimestamp, | ||
instanceId: contact.lastMessageInstanceId, | ||
sessionId: contact.lastMessageSessionId, | ||
status: contact.lastMessageStatus, | ||
} | ||
: undefined; | ||
|
||
return { | ||
id: contact.contactid || null, | ||
remoteJid: contact.remotejid, | ||
pushName: contact.pushname, | ||
profilePicUrl: contact.profilepicurl, | ||
updatedAt: contact.updatedat, | ||
windowStart: contact.windowstart, | ||
windowExpires: contact.windowexpires, | ||
windowActive: contact.windowactive, | ||
id: contact.contactId || null, | ||
remoteJid: contact.remoteJid, | ||
pushName: contact.pushName, | ||
profilePicUrl: contact.profilePicUrl, | ||
updatedAt: contact.updatedAt, | ||
windowStart: contact.windowStart, | ||
windowExpires: contact.windowExpires, | ||
windowActive: contact.windowActive, | ||
lastMessage: lastMessage ? this.cleanMessageData(lastMessage) : undefined, | ||
unreadCount: 0, | ||
isSaved: !!contact.contactid, | ||
unreadCount: contact.unreadMessages, | ||
isSaved: !!contact.contactId, | ||
}; | ||
}); | ||
|
||
if (query?.take && query?.skip) { | ||
const skip = query.skip || 0; | ||
const take = query.take || 20; | ||
return mappedResults.slice(skip, skip + take); | ||
} | ||
|
||
return mappedResults; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion (code-quality): Inline variable that is immediately returned (inline-immediately-returned-variable
)
const mappedResults = results.map((contact) => { | |
const lastMessage = contact.lastmessageid | |
const lastMessage = contact.lastMessageId | |
? { | |
id: contact.lastmessageid, | |
key: contact.lastmessage_key, | |
pushName: contact.lastmessagepushname, | |
participant: contact.lastmessageparticipant, | |
messageType: contact.lastmessagemessagetype, | |
message: contact.lastmessagemessage, | |
contextInfo: contact.lastmessagecontextinfo, | |
source: contact.lastmessagesource, | |
messageTimestamp: contact.lastmessagemessagetimestamp, | |
instanceId: contact.lastmessageinstanceid, | |
sessionId: contact.lastmessagesessionid, | |
status: contact.lastmessagestatus, | |
id: contact.lastMessageId, | |
key: contact.lastMessage_key, | |
pushName: contact.lastMessagePushName, | |
participant: contact.lastMessageParticipant, | |
messageType: contact.lastMessageMessageType, | |
message: contact.lastMessageMessage, | |
contextInfo: contact.lastMessageContextInfo, | |
source: contact.lastMessageSource, | |
messageTimestamp: contact.lastMessageMessageTimestamp, | |
instanceId: contact.lastMessageInstanceId, | |
sessionId: contact.lastMessageSessionId, | |
status: contact.lastMessageStatus, | |
} | |
: undefined; | |
return { | |
id: contact.contactid || null, | |
remoteJid: contact.remotejid, | |
pushName: contact.pushname, | |
profilePicUrl: contact.profilepicurl, | |
updatedAt: contact.updatedat, | |
windowStart: contact.windowstart, | |
windowExpires: contact.windowexpires, | |
windowActive: contact.windowactive, | |
id: contact.contactId || null, | |
remoteJid: contact.remoteJid, | |
pushName: contact.pushName, | |
profilePicUrl: contact.profilePicUrl, | |
updatedAt: contact.updatedAt, | |
windowStart: contact.windowStart, | |
windowExpires: contact.windowExpires, | |
windowActive: contact.windowActive, | |
lastMessage: lastMessage ? this.cleanMessageData(lastMessage) : undefined, | |
unreadCount: 0, | |
isSaved: !!contact.contactid, | |
unreadCount: contact.unreadMessages, | |
isSaved: !!contact.contactId, | |
}; | |
}); | |
if (query?.take && query?.skip) { | |
const skip = query.skip || 0; | |
const take = query.take || 20; | |
return mappedResults.slice(skip, skip + take); | |
} | |
return mappedResults; | |
return results.map((contact) => { | |
const lastMessage = contact.lastMessageId | |
? { | |
id: contact.lastMessageId, | |
key: contact.lastMessage_key, | |
pushName: contact.lastMessagePushName, | |
participant: contact.lastMessageParticipant, | |
messageType: contact.lastMessageMessageType, | |
message: contact.lastMessageMessage, | |
contextInfo: contact.lastMessageContextInfo, | |
source: contact.lastMessageSource, | |
messageTimestamp: contact.lastMessageMessageTimestamp, | |
instanceId: contact.lastMessageInstanceId, | |
sessionId: contact.lastMessageSessionId, | |
status: contact.lastMessageStatus, | |
} | |
: undefined; | |
return { | |
id: contact.contactId || null, | |
remoteJid: contact.remoteJid, | |
pushName: contact.pushName, | |
profilePicUrl: contact.profilePicUrl, | |
updatedAt: contact.updatedAt, | |
windowStart: contact.windowStart, | |
windowExpires: contact.windowExpires, | |
windowActive: contact.windowActive, | |
lastMessage: lastMessage ? this.cleanMessageData(lastMessage) : undefined, | |
unreadCount: contact.unreadMessages, | |
isSaved: !!contact.contactId, | |
}; | |
}); | |
Explanation
Something that we often see in people's code is assigning to a result variableand then immediately returning it.
Returning the result directly shortens the code and removes an unnecessary
variable, reducing the mental load of reading the function.
Where intermediate variables can be useful is if they then get used as a
parameter or a condition, and the name can act like a comment on what the
variable represents. In the case where you're returning it from a function, the
function name is there to tell you what the result is, so the variable name
is unnecessary.
Bug Fix: Inconsistent Column Alias Casing in
fetchChats
Bug description: #1691
Context
In PostgreSQL, unquoted column aliases are automatically lowercased. In our
channel.service.ts → fetchChats
query, there was a mix of quoted and unquoted aliases, causing PostgreSQL to return fields likeupdatedat
andwindowstart
instead of the expectedupdatedAt
andwindowStart
.This inconsistency broke or skipped field mappings in the application layer.
Additionally, the pagination logic was applied twice due to redundant filtering, which led to incorrect result sets when paginating chat data.
Changes Made
OFFSET
andLIMIT
behavior for chat pagination.Affected Environments
Outcome
Summary by Sourcery
Fix inconsistent column alias casing and eliminate duplicate pagination logic in the chat fetch query to restore proper field mappings and accurate paging.
Bug Fixes: