Skip to content

Added prisma extension to convert "path" in array format (postgresql) to string format (mysql) #1535

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

Open
wants to merge 4 commits into
base: develop
Choose a base branch
from

Conversation

w35l3y
Copy link

@w35l3y w35l3y commented Jun 1, 2025

Este PR deve resolver os seguintes erros:

  1. Argument path: Invalid value provided. Expected String, provided (String).
  2. Argument status is missing.

O 1o erro ocorre sempre que há alguma consulta que envolve buscar algo em um campo JSON.
Por exemplo:

where: {
  key: {
    path: ['id'], // <- PostgreSQL
    equals: messageId,
  }
}

De acordo com a documentação do Prisma, o formato esperado para trabalhar com MySQL é o seguinte:

where: {
  key: {
    path: '$.id', // <- MySQL
    equals: messageId,
  }
}

A solução proposta foi criar uma extensão que é aplicada em tempo de execução quando se está usando o provider "mysql".
Ou seja, a aplicação continua usando o formato de array (postgresql) e a extensão processa a cláusula where de forma recursiva e converte o "path" em string.

Para maiores detalhes, segue links da documentação:

O 2o erro aconteceu comigo quando recebi uma mensagem editada.
Mensagens editadas não possuem status.
Então, o campo "status" terminava ficando indefinido.
Como "status" é um campo obrigatório no banco, lança o erro.

A solução proposta para este caso foi atribuir o status da mensagem original quando este for indefinido.

Summary by Sourcery

Add runtime Prisma extension to convert PostgreSQL-style JSON path arrays into MySQL JSON path strings and apply it via a proxy when using the MySQL provider, fix missing message status fallback, and enable JavaScript support in tsconfig.

New Features:

  • Add Prisma client extension to transform PG-style JSON path arrays into MySQL JSON path strings at runtime.
  • Apply the extension transparently via an extendsWithProxy wrapper when the MySQL provider is used.

Bug Fixes:

  • Fallback to the original message status when update.status is undefined to prevent missing status errors.

Build:

  • Enable allowJs in tsconfig to include the new JavaScript Prisma extension file.

w35l3y added 2 commits June 1, 2025 17:25
Added prisma extension to convert "path" from array format (postgresql) to string format (mysql)
Copy link
Contributor

sourcery-ai bot commented Jun 1, 2025

Reviewer's Guide

Introduces a Prisma Client extension that converts PostgreSQL-style JSON path arrays into MySQL-compatible string paths at runtime via a proxy wrapper for the MySQL provider, adds a fallback for missing message status in the WhatsApp service, and enables JS support to compile the new extension.

Sequence Diagram for JSON Path Conversion in Prisma Queries

sequenceDiagram
    actor ClientCode as "Application Code"
    participant PR_Proxy as "PrismaRepository (MySQL Proxy)"
    participant Ext as "pgPathToMysql Extension"
    participant PrismaCore as "Prisma Client Core"
    participant DB as "MySQL Database"

    ClientCode->>PR_Proxy: Query with JSON array path (e.g., findFirst({ where: { data: { path: ['field'] } } }))
    PR_Proxy->>Ext: overriddenOperation(args)
    Ext->>Ext: processWhere(args.where)
    Ext->>Ext: convertPgPathToMysql(['field'])
    Note right of Ext: Converts ['field'] to '$.field'
    Ext-->>PR_Proxy: Modified args with string path
    PR_Proxy->>PrismaCore: query(modifiedArgs)
    PrismaCore->>DB: Execute SQL with '$.field'
    DB-->>PrismaCore: Query Result
    PrismaCore-->>PR_Proxy: Query Result
    PR_Proxy-->>ClientCode: Query Result
Loading

Sequence Diagram for Message Status Fallback Logic

sequenceDiagram
    participant WhatsApp as "WhatsApp Event Source"
    participant BSS as "BaileysStartupService"
    participant Repo as "PrismaRepository"

    WhatsApp->>BSS: Message Update (e.g., edited, status undefined)
    BSS->>BSS: Process update: update.status is undefined
    BSS->>BSS: Use findMessage.status as fallback for message.status
    Note right of BSS: new_status = status[update.status] // undefined<br/>  || findMessage.status // used
    BSS->>BSS: Prepare message data with resolved status
    BSS->>Repo: Save/Update message data
Loading

File-Level Changes

Change Details Files
Implement JSON path conversion extension for Prisma Client
  • Create recursive path converter from array to string format
  • Define client extension to intercept and modify all query operations
  • Log model, operation, arguments, and results for debugging
src/api/extensions/prismaExtensionPgpathToMysql.js
Provide a proxy-based wrapper to apply Prisma extensions
  • Define a generic function to extend PrismaClient with given extension
  • Use Proxy to merge base client and extended client methods
  • Handle toString and symbol tagging in proxy implementation
src/utils/extendsWithProxy.ts
Conditionally apply proxy-wrapped Prisma repository for MySQL
  • Import and detect database provider at runtime
  • Wrap repository instance with proxy extension when provider is MySQL
  • Export extended or base repository accordingly
src/api/server.module.ts
tsconfig.json
Add fallback for undefined message status in WhatsApp service
  • Use original message status when update status is undefined
  • Prevent database errors from missing required status field
src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts

Assessment against linked issues

Issue Objective Addressed Explanation
#1158 Fix the Invalid this.cache.delete() invocation error caused by the path argument expecting a String but receiving a String array when using MySQL.
#1158 Handle the missing status argument when receiving edited messages to prevent errors due to the status field being mandatory in the database.
#1367 The fromMe field in the messages.edited event should be false when the user editing the message is not the instance itself. The PR addresses two other issues related to Prisma and message status, but it does not address the issue of the fromMe field being incorrectly set to true in the messages.edited event.
#1367 The remoteJid field in the messages.edited event should be the number of the user who edited the message (the sender), not the instance number. The PR addresses two other issues related to Prisma and message status, but it does not address the issue of the remoteJid field being incorrectly set in the messages.edited event.

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 @w35l3y - I've reviewed your changes - here's some feedback:

  • The processWhere function mutates the original args.where object in place—consider cloning it first to avoid unexpected side-effects on shared objects.
  • The extendsWithProxy Proxy wrapper adds complexity to the Prisma client—consider using PrismaClient.$extends directly to simplify typing and client behavior.
  • You’re logging full query args and results on every operation—restrict or sanitize these debug logs in production to avoid performance hits and leaking sensitive data.
Here's what I looked at during the review
  • 🟡 General issues: 2 issues found
  • 🟢 Security: all looks good
  • 🟢 Testing: all looks good
  • 🟢 Documentation: all looks good

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.

@w35l3y w35l3y changed the title Added prisma extension to "convert" path in array format (postgresql) to string format (mysql) Added prisma extension to convert "path" in array format (postgresql) to string format (mysql) Jun 1, 2025
@DavidsonGomes DavidsonGomes changed the base branch from main to develop June 3, 2025 15:37
@w35l3y
Copy link
Author

w35l3y commented Jun 5, 2025

@DavidsonGomes , resolvi a situação do lint, mas o conflito... no meu caso, aconteceu quando a mensagem foi editada.

Para mim, não faria sentido ficar com o status de DELETED.
Por este motivo, coloquei para recuperar o status anterior.
Que também não me parece ideal, mas foi a opção que cogitei no momento.

Vocês entendem melhor o projeto como um todo e podem ter uma ideia diferente da minha.
Até se for o caso, um status completamente diferente para mensagens editadas.
Ou simplesmente manter o DELETED e vida que segue. 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
1 participant