Skip to content

fix(engine): resolve lint-staged and json path typing#2481

Open
shajandevz wants to merge 1 commit intoEvolutionAPI:mainfrom
shajandevz:fix/engine-changes
Open

fix(engine): resolve lint-staged and json path typing#2481
shajandevz wants to merge 1 commit intoEvolutionAPI:mainfrom
shajandevz:fix/engine-changes

Conversation

@shajandevz
Copy link

@shajandevz shajandevz commented Mar 20, 2026

📋 Description

🔗 Related Issue

Closes #(issue_number)

🧪 Type of Change

  • 🐛 Bug fix (non-breaking change which fixes an issue)
  • ✨ New feature (non-breaking change which adds functionality)
  • 💥 Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • 📚 Documentation update
  • 🔧 Refactoring (no functional changes)
  • ⚡ Performance improvement
  • 🧹 Code cleanup
  • 🔒 Security fix

🧪 Testing

  • Manual testing completed
  • Functionality verified in development environment
  • No breaking changes introduced
  • Tested with different connection types (if applicable)

📸 Screenshots (if applicable)

✅ Checklist

  • My code follows the project's style guidelines
  • I have performed a self-review of my code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have manually tested my changes thoroughly
  • I have verified the changes work with different scenarios
  • Any dependent changes have been merged and published

📝 Additional Notes

Summary by Sourcery

Align message JSON path queries and label persistence with database requirements, and update tooling configuration for linting and Nx integration.

Bug Fixes:

  • Fix label deletion and update logic to use primary key IDs instead of composite keys, preventing inconsistencies when labels change.
  • Correct Prisma JSON path usage for message key filters to use string JSONPath expressions, avoiding JSON path type issues across databases.
  • Ensure unread message counters and read-status updates work for both Postgres and MySQL by adjusting raw SQL to the appropriate JSON functions and syntax.
  • Restore compatibility of on-whatsapp cache behavior by deriving the lid field at read-time instead of storing and comparing it in the cache.

Enhancements:

  • Add an explicit return type to the WhatsApp Baileys fetchMessages method to satisfy typing expectations.
  • Introduce an Nx project.json for the engine app to define serve, build and database-related targets.

Build:

  • Set ESLINT_USE_FLAT_CONFIG in lint and lint-staged commands to avoid flat-config resolution issues with eslint.

@sourcery-ai
Copy link
Contributor

sourcery-ai bot commented Mar 20, 2026

Reviewer's Guide

This pull request fixes Prisma JSON path usage for message keys, adjusts label persistence logic, adds MySQL-specific raw SQL for message read/unread calculations, simplifies the WhatsApp cache lid handling, wires ESLint to work correctly with lint-staged via the flat config env flag, and introduces an Nx project.json for the engine app.

Flow diagram for updateChatUnreadMessages with MySQL and Postgres paths

flowchart TD
  A[updateChatUnreadMessages remoteJid] --> B[Read DATABASE.PROVIDER from configService]
  B --> C[Normalize provider to lowercase]
  C --> D{dbProvider is mysql}
  D -->|yes| E[Find chat by remoteJid via prismaRepository.chat.findFirst]
  E --> F[Query unreadMessages count with MySQL raw SQL using JSON_EXTRACT on key.remoteJid and key.fromMe]
  D -->|no| G[Find chat by remoteJid via prismaRepository.chat.findFirst]
  G --> H[Query unreadMessages count with Postgres raw SQL using key->>'remoteJid' and key->>'fromMe']
  F --> I[Receive unreadMessages number]
  H --> I[Receive unreadMessages number]
  I --> J{chat exists and chat.unreadMessages != unreadMessages}
  J -->|yes| K[Update chat.unreadMessages with unreadMessages]
  J -->|no| L[Skip chat update]
  K --> M[Return unreadMessages]
  L --> M[Return unreadMessages]
Loading

Flow diagram for saveOnWhatsappCache with simplified lid handling

flowchart TD
  A[saveOnWhatsappCache data array] --> B[Iterate over each item]
  B --> C[Normalize remoteJid]
  C --> D[Build finalJidOptions set]
  D --> E[Sort finalJidOptions]
  E --> F[Create newJidOptionsString]
  F --> G[Build dataPayload with remoteJid and jidOptions]
  G --> H[Search existingRecord in prismaRepository.isOnWhatsapp by remoteJid]
  H --> I{existingRecord found}
  I -->|yes| J[Build existingJidOptionsString from existingRecord.jidOptions]
  J --> K[Compare existingRecord.remoteJid and existingJidOptionsString with dataPayload]
  K --> L{Data is same}
  L -->|yes| M[Log verbose: data up to date, skip update]
  L -->|no| N[Log verbose: updating register]
  N --> O[Update existingRecord with dataPayload]
  M --> P[Continue with next item]
  O --> P[Continue with next item]
  I -->|no| Q[Log verbose: creating register]
  Q --> R[Create new record in prismaRepository.isOnWhatsapp with dataPayload]
  R --> P[Continue with next item]
Loading

Flow diagram for getOnWhatsappCache lid resolution at read time

flowchart TD
  A[getOnWhatsappCache remoteJids] --> B[Fetch records from prismaRepository.isOnWhatsapp]
  B --> C[Iterate over each item]
  C --> D[Split item.jidOptions into array]
  D --> E[Compute number from item.remoteJid prefix]
  E --> F[Determine lid]
  F --> G{item has lid property}
  G -->|yes| H[Use item.lid]
  G -->|no| I{item.remoteJid includes @lid}
  I -->|yes| J[Set lid to lid]
  I -->|no| K[Set lid to undefined]
  H --> L[Build output object with remoteJid number jidOptions and lid]
  J --> L[Build output object with remoteJid number jidOptions and lid]
  K --> L[Build output object with remoteJid number jidOptions and lid]
  L --> M[Collect all output objects and return]
Loading

File-Level Changes

Change Details Files
Align Prisma JSON path filters for message keys with string-based JSON path syntax across services.
  • Replaced array-style JSON path usage (e.g., path: ['id']) with string JSONPath syntax (e.g., path: '$.id') in Prisma queries for messages.
  • Updated message fetch filters in BaileysStartupService and ChannelStartupService to use consistent '$.' paths for id, fromMe, participant, remoteJid, and remoteJidAlt.
  • Adjusted ChatwootService and BusinessStartupService queries that match on key.id and key.fromMe to use the string path format.
src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts
src/api/services/channel.service.ts
src/api/integrations/chatbot/chatwoot/services/chatwoot.service.ts
src/api/integrations/channel/meta/whatsapp.business.service.ts
Fix label persistence logic to operate on primary key IDs instead of composite labelId/instanceId constraint.
  • When deleting labels, use the saved label's primary key id in the Prisma delete where clause instead of the labelId_instanceId composite key.
  • Replaced label upsert on labelId_instanceId with explicit update-by-id when a savedLabel exists and create otherwise.
src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts
Add database-provider-aware raw SQL for read/unread message status and unread count calculations.
  • Introduced dbProvider detection from config to branch behavior between MySQL and Postgres.
  • For MySQL, added $executeRaw update on Message using JSON_EXTRACT/JSON_UNQUOTE and boolean checks on key.fromMe and messageTimestamp, with follow-up unread chat update when rows are affected.
  • For MySQL, added $queryRaw unread count query on Message using JSON_EXTRACT/JSON_UNQUOTE; retained existing Postgres JSON operator queries as the fallback path.
  • Preserved existing Postgres raw SQL as the default behavior when provider is not MySQL.
src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts
Simplify and centralize lid handling in the WhatsApp cache utilities to avoid storing lid redundantly.
  • Removed lid from the dataPayload that is persisted to the isOnWhatsapp table and from the equality check used to skip updates.
  • Adjusted verbose logs to drop lid details when creating or updating cache entries.
  • On read, derive lid from the record dynamically: prefer item.lid if present (with a type cast) and otherwise infer 'lid' from remoteJid containing '@lid'.
src/utils/onWhatsappCache.ts
Ensure ESLint works correctly with lint-staged and Nx by pinning the non-flat config mode and adding project metadata.
  • Updated lint and lint:check npm scripts to force ESLINT_USE_FLAT_CONFIG=false for eslint invocations.
  • Wrapped lint-staged eslint command in a shell call that also sets ESLINT_USE_FLAT_CONFIG=false, so staged file linting uses the same configuration.
  • Added an Nx project.json for the engine app, wiring serve, build, db:migrate, and db:seed targets to the corresponding npm scripts in apps/engine.
  • Ensured project tags identify the engine as an application with scope:engine.
package.json
project.json

Possibly linked issues

  • #(unprovided): PR corrects JSON path strings, label where clauses, and onWhatsapp types, resolving the TypeScript/Prisma build errors described.

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 1 issue, and left some high level feedback:

  • The new JSON path usage (e.g. key: { path: '$.id', ... }) diverges from Prisma’s typical string[] path typing; consider encapsulating provider-specific JSON path handling in a small helper or type-safe abstraction instead of sprinkling raw JSONPath strings throughout the code.
  • The fetchMessages method now returns Promise<any>; tightening this to the concrete Prisma return type (or a well-defined interface) will help catch issues at compile time and make the call sites clearer.
  • The new project.json declares sourceRoot: 'apps/engine/src' and uses a $schema path with ../../node_modules, which suggests it may be intended to live under apps/engine; double-check the file’s location and paths so Nx picks it up correctly without relying on potentially incorrect relative paths.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The new JSON path usage (e.g. `key: { path: '$.id', ... }`) diverges from Prisma’s typical `string[]` path typing; consider encapsulating provider-specific JSON path handling in a small helper or type-safe abstraction instead of sprinkling raw JSONPath strings throughout the code.
- The `fetchMessages` method now returns `Promise<any>`; tightening this to the concrete Prisma return type (or a well-defined interface) will help catch issues at compile time and make the call sites clearer.
- The new `project.json` declares `sourceRoot: 'apps/engine/src'` and uses a `$schema` path with `../../node_modules`, which suggests it may be intended to live under `apps/engine`; double-check the file’s location and paths so Nx picks it up correctly without relying on potentially incorrect relative paths.

## Individual Comments

### Comment 1
<location path="src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts" line_range="5050" />
<code_context>
   }

-  public async fetchMessages(query: Query<Message>) {
+  public async fetchMessages(query: Query<Message>): Promise<any> {
     const keyFilters = query?.where?.key as ExtendedIMessageKey;

</code_context>
<issue_to_address>
**suggestion:** The `fetchMessages` return type `Promise<any>` loses useful typing information.

The method used to infer its return type from `prismaRepository.message.findMany`/`findFirst`, but explicitly returning `Promise<any>` hides the data shape and removes type safety and editor/compiler assistance for callers.

Please narrow the return type to the concrete message type (e.g. `Promise<Message[]>` or an appropriate Prisma type such as `Prisma.MessageGetPayload<...>`), matching what the method actually returns, so the service API remains type-safe without changing runtime behavior.

```suggestion
  public async fetchMessages(query: Query<Message>) {
```
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

}

public async fetchMessages(query: Query<Message>) {
public async fetchMessages(query: Query<Message>): Promise<any> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: The fetchMessages return type Promise<any> loses useful typing information.

The method used to infer its return type from prismaRepository.message.findMany/findFirst, but explicitly returning Promise<any> hides the data shape and removes type safety and editor/compiler assistance for callers.

Please narrow the return type to the concrete message type (e.g. Promise<Message[]> or an appropriate Prisma type such as Prisma.MessageGetPayload<...>), matching what the method actually returns, so the service API remains type-safe without changing runtime behavior.

Suggested change
public async fetchMessages(query: Query<Message>): Promise<any> {
public async fetchMessages(query: Query<Message>) {

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant