-
Notifications
You must be signed in to change notification settings - Fork 5.9k
issue fixed #2487
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?
issue fixed #2487
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| { | ||
| "name": "engine", | ||
| "$schema": "../../node_modules/nx/schemas/project-schema.json", | ||
| "sourceRoot": "apps/engine/src", | ||
| "projectType": "application", | ||
| "prefix": "engine", | ||
| "targets": { | ||
| "serve": { | ||
| "executor": "nx:run-commands", | ||
| "options": { | ||
| "command": "npm run dev:server", | ||
| "cwd": "apps/engine" | ||
| } | ||
| }, | ||
| "build": { | ||
| "executor": "nx:run-commands", | ||
| "options": { | ||
| "command": "npm run build", | ||
| "cwd": "apps/engine" | ||
| } | ||
| }, | ||
| "db:migrate": { | ||
| "executor": "nx:run-commands", | ||
| "options": { | ||
| "command": "npm run db:deploy", | ||
| "cwd": "apps/engine" | ||
| } | ||
| }, | ||
| "db:seed": { | ||
| "executor": "nx:run-commands", | ||
| "options": { | ||
| "command": "npm run db:seed", | ||
| "cwd": "apps/engine" | ||
| } | ||
| } | ||
| }, | ||
| "tags": ["type:app", "scope:engine"] | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1819,7 +1819,7 @@ export class BaileysStartupService extends ChannelStartupService { | |
| const savedLabel = labelsRepository.find((l) => l.labelId === label.id); | ||
| if (label.deleted && savedLabel) { | ||
| await this.prismaRepository.label.delete({ | ||
| where: { labelId_instanceId: { instanceId: this.instanceId, labelId: label.id } }, | ||
| where: { id: savedLabel.id }, | ||
| }); | ||
| this.sendDataWebhook(Events.LABELS_EDIT, { ...label, instance: this.instance.name }); | ||
| return; | ||
|
|
@@ -1835,11 +1835,16 @@ export class BaileysStartupService extends ChannelStartupService { | |
| predefinedId: label.predefinedId, | ||
| instanceId: this.instanceId, | ||
| }; | ||
| await this.prismaRepository.label.upsert({ | ||
| where: { labelId_instanceId: { instanceId: labelData.instanceId, labelId: labelData.labelId } }, | ||
| update: labelData, | ||
| create: labelData, | ||
| }); | ||
| if (savedLabel) { | ||
| await this.prismaRepository.label.update({ | ||
| where: { id: savedLabel.id }, | ||
| data: labelData, | ||
| }); | ||
| } else { | ||
| await this.prismaRepository.label.create({ | ||
| data: labelData, | ||
| }); | ||
| } | ||
| } | ||
| } | ||
| }, | ||
|
|
@@ -3776,7 +3781,7 @@ export class BaileysStartupService extends ChannelStartupService { | |
| if (messageId) { | ||
| const isLogicalDeleted = configService.get<Database>('DATABASE').DELETE_DATA.LOGICAL_MESSAGE_DELETE; | ||
| let message = await this.prismaRepository.message.findFirst({ | ||
| where: { key: { path: ['id'], equals: messageId } }, | ||
| where: { key: { path: '$.id', equals: messageId } }, | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. issue (bug_risk): Using string JSON paths ( Prismaβs JSON filter This change appears in multiple places (e.g. |
||
| }); | ||
| if (isLogicalDeleted) { | ||
| if (!message) return response; | ||
|
|
@@ -4196,7 +4201,7 @@ export class BaileysStartupService extends ChannelStartupService { | |
| const messageId = messageSent.message?.protocolMessage?.key?.id; | ||
| if (messageId && this.configService.get<Database>('DATABASE').SAVE_DATA.NEW_MESSAGE) { | ||
| let message = await this.prismaRepository.message.findFirst({ | ||
| where: { key: { path: ['id'], equals: messageId } }, | ||
| where: { key: { path: '$.id', equals: messageId } }, | ||
| }); | ||
| if (!message) throw new NotFoundException('Message not found'); | ||
|
|
||
|
|
@@ -4734,6 +4739,26 @@ export class BaileysStartupService extends ChannelStartupService { | |
| private async updateMessagesReadedByTimestamp(remoteJid: string, timestamp?: number): Promise<number> { | ||
| if (timestamp === undefined || timestamp === null) return 0; | ||
|
|
||
| const dbProvider = String(this.configService.get<Database>('DATABASE')?.PROVIDER || '').toLowerCase(); | ||
|
|
||
| if (dbProvider === 'mysql') { | ||
| const result = await this.prismaRepository.$executeRaw` | ||
| UPDATE \`Message\` | ||
| SET \`status\` = ${status[4]} | ||
| WHERE \`instanceId\` = ${this.instanceId} | ||
| AND JSON_UNQUOTE(JSON_EXTRACT(\`key\`, '$.remoteJid')) = ${remoteJid} | ||
| AND JSON_EXTRACT(\`key\`, '$.fromMe') = false | ||
| AND \`messageTimestamp\` <= ${timestamp} | ||
| AND (\`status\` IS NULL OR \`status\` = ${status[3]}) | ||
| `; | ||
|
|
||
| if (result && result > 0) { | ||
| this.updateChatUnreadMessages(remoteJid); | ||
| } | ||
|
|
||
| return result || 0; | ||
| } | ||
|
|
||
| // Use raw SQL to avoid JSON path issues | ||
| const result = await this.prismaRepository.$executeRaw` | ||
| UPDATE "Message" | ||
|
|
@@ -4757,16 +4782,25 @@ export class BaileysStartupService extends ChannelStartupService { | |
| } | ||
|
|
||
| private async updateChatUnreadMessages(remoteJid: string): Promise<number> { | ||
| const dbProvider = String(this.configService.get<Database>('DATABASE')?.PROVIDER || '').toLowerCase(); | ||
|
|
||
| const [chat, unreadMessages] = await Promise.all([ | ||
| this.prismaRepository.chat.findFirst({ where: { remoteJid } }), | ||
| // Use raw SQL to avoid JSON path issues | ||
| this.prismaRepository.$queryRaw` | ||
| SELECT COUNT(*)::int as count FROM "Message" | ||
| WHERE "instanceId" = ${this.instanceId} | ||
| AND "key"->>'remoteJid' = ${remoteJid} | ||
| AND ("key"->>'fromMe')::boolean = false | ||
| AND "status" = ${status[3]} | ||
| `.then((result: any[]) => result[0]?.count || 0), | ||
| dbProvider === 'mysql' | ||
| ? this.prismaRepository.$queryRaw` | ||
| SELECT COUNT(*) as count FROM \`Message\` | ||
| WHERE \`instanceId\` = ${this.instanceId} | ||
| AND JSON_UNQUOTE(JSON_EXTRACT(\`key\`, '$.remoteJid')) = ${remoteJid} | ||
| AND JSON_EXTRACT(\`key\`, '$.fromMe') = false | ||
| AND \`status\` = ${status[3]} | ||
| `.then((result: any[]) => Number(result?.[0]?.count || 0)) | ||
| : this.prismaRepository.$queryRaw` | ||
| SELECT COUNT(*)::int as count FROM "Message" | ||
| WHERE "instanceId" = ${this.instanceId} | ||
| AND "key"->>'remoteJid' = ${remoteJid} | ||
| AND ("key"->>'fromMe')::boolean = false | ||
| AND "status" = ${status[3]} | ||
| `.then((result: any[]) => result[0]?.count || 0), | ||
| ]); | ||
|
|
||
| if (chat && chat.unreadMessages !== unreadMessages) { | ||
|
|
@@ -5013,7 +5047,7 @@ export class BaileysStartupService extends ChannelStartupService { | |
| } | ||
| } | ||
|
|
||
| public async fetchMessages(query: Query<Message>) { | ||
| public async fetchMessages(query: Query<Message>): Promise<any> { | ||
| const keyFilters = query?.where?.key as ExtendedIMessageKey; | ||
|
|
||
| const timestampFilter = {}; | ||
|
Comment on lines
-5016
to
5019
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. suggestion: Loosening This change hides the actual result shape from callers and removes compile-time checks on returned fields. If you need to support multiple result shapes (e.g., DB-specific raw results), prefer a typed union or a dedicated interface/DTO over Suggested implementation: public async fetchMessages(query: Query<Message>): Promise<Message[]> {If
|
||
|
|
@@ -5034,13 +5068,13 @@ export class BaileysStartupService extends ChannelStartupService { | |
| messageType: query?.where?.messageType, | ||
| ...timestampFilter, | ||
| AND: [ | ||
| keyFilters?.id ? { key: { path: ['id'], equals: keyFilters?.id } } : {}, | ||
| keyFilters?.fromMe ? { key: { path: ['fromMe'], equals: keyFilters?.fromMe } } : {}, | ||
| keyFilters?.participant ? { key: { path: ['participant'], equals: keyFilters?.participant } } : {}, | ||
| keyFilters?.id ? { key: { path: '$.id', equals: keyFilters?.id } } : {}, | ||
| keyFilters?.fromMe ? { key: { path: '$.fromMe', equals: keyFilters?.fromMe } } : {}, | ||
| keyFilters?.participant ? { key: { path: '$.participant', equals: keyFilters?.participant } } : {}, | ||
| { | ||
| OR: [ | ||
| keyFilters?.remoteJid ? { key: { path: ['remoteJid'], equals: keyFilters?.remoteJid } } : {}, | ||
| keyFilters?.remoteJidAlt ? { key: { path: ['remoteJidAlt'], equals: keyFilters?.remoteJidAlt } } : {}, | ||
| keyFilters?.remoteJid ? { key: { path: '$.remoteJid', equals: keyFilters?.remoteJid } } : {}, | ||
| keyFilters?.remoteJidAlt ? { key: { path: '$.remoteJidAlt', equals: keyFilters?.remoteJidAlt } } : {}, | ||
| ], | ||
| }, | ||
| ], | ||
|
|
@@ -5063,13 +5097,13 @@ export class BaileysStartupService extends ChannelStartupService { | |
| messageType: query?.where?.messageType, | ||
| ...timestampFilter, | ||
| AND: [ | ||
| keyFilters?.id ? { key: { path: ['id'], equals: keyFilters?.id } } : {}, | ||
| keyFilters?.fromMe ? { key: { path: ['fromMe'], equals: keyFilters?.fromMe } } : {}, | ||
| keyFilters?.participant ? { key: { path: ['participant'], equals: keyFilters?.participant } } : {}, | ||
| keyFilters?.id ? { key: { path: '$.id', equals: keyFilters?.id } } : {}, | ||
| keyFilters?.fromMe ? { key: { path: '$.fromMe', equals: keyFilters?.fromMe } } : {}, | ||
| keyFilters?.participant ? { key: { path: '$.participant', equals: keyFilters?.participant } } : {}, | ||
| { | ||
| OR: [ | ||
| keyFilters?.remoteJid ? { key: { path: ['remoteJid'], equals: keyFilters?.remoteJid } } : {}, | ||
| keyFilters?.remoteJidAlt ? { key: { path: ['remoteJidAlt'], equals: keyFilters?.remoteJidAlt } } : {}, | ||
| keyFilters?.remoteJid ? { key: { path: '$.remoteJid', equals: keyFilters?.remoteJid } } : {}, | ||
| keyFilters?.remoteJidAlt ? { key: { path: '$.remoteJidAlt', equals: keyFilters?.remoteJidAlt } } : {}, | ||
| ], | ||
| }, | ||
| ], | ||
|
|
||
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.
issue (bug_risk): The
$schemapath may be incorrect relative to the location ofproject.json.Since this
project.jsonis at the repo root andsourceRootisapps/engine/src, the schema file should likely be referenced asnode_modules/nx/schemas/project-schema.json(no../segments). The current../../node_modules/...path would resolve above the repo root and likely break Nx/IDE schema validation. Please verify the actual schema location and update the path accordingly so tooling can validate this config.