Repository navigation
fix(mysql): JSON path filters, Label unique key and chat label updates on MySQL - #2772
omaralalwi wants to merge 1 commit into
Conversation
- Prisma JSON field filters take the path as an array on PostgreSQL but as a '$.field' string on MySQL; add a jsonPath() helper and use it for every key filter, so message lookups by key no longer fail validation. - Add the (labelId, instanceId) unique key to the MySQL schema with a migration; the Baileys label sync upserts on it. - addLabel/removeLabel (MySQL): skip a label that is already present, and stop wiping all chat labels when removing one that is not there (JSON_SEARCH returned NULL).
Reviewer's GuideFixes the remaining MySQL-specific failures by selecting the correct Prisma JSON path format, adding the composite Label uniqueness key and migration, and making chat label add/remove SQL operations safe and idempotent, while preserving PostgreSQL behavior. Sequence diagram for database-aware JSON path filteringsequenceDiagram
participant Service
participant jsonPath
participant Prisma
participant Database
Service->>jsonPath: jsonPath('id')
alt MySQL provider
jsonPath-->>Service: '$.id'
else PostgreSQL provider
jsonPath-->>Service: ['id']
end
Service->>Prisma: findFirst or findMany with key.path
Prisma->>Database: Execute JSON path filter
Database-->>Prisma: Matching messages
Entity relationship diagram for the MySQL Label uniqueness keyerDiagram
Label {
string labelId
string instanceId
string labelId_instanceId UK
}
Label }o--|| Instance : belongs_to
Flow diagram for idempotent MySQL chat label updatesflowchart TD
Event[Chat label event] --> Contains{JSON_CONTAINS label?}
Contains -->|Add and present| Keep[Keep labels unchanged]
Contains -->|Add and absent| Append[JSON_ARRAY_APPEND label]
Contains -->|Remove and present| Search[JSON_SEARCH with escaped label]
Search --> Remove[JSON_REMOVE matched label]
Contains -->|Remove and absent| Preserve[Preserve existing labels]
Append --> Updated[Update chat labels]
Remove --> Updated
Keep --> Updated
Preserve --> Updated
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Hey - I've reviewed your changes and they look great!
Sourcery assessment
Needs a human reviewer. The MySQL upsert changes stored chat-label arrays, so a faulty duplicate check or removal could leave labels missing or duplicated; reverting the code would not undo those changes, though the affected labels can be corrected. The new unique index can also make writes fail if the assumed per-instance uniqueness is wrong, but removing the index reverses that constraint.
📋 Description
developalready has MySQL variants for the raw SQL queries, but three MySQL paths are still broken. This PR fixes them and leaves PostgreSQL behaviour unchanged.1. Prisma JSON path filters use the PostgreSQL form
Every
key: { path: ['id'], … }filter passes the path as an array. Prisma only accepts that on PostgreSQL; on MySQL the path must be a JSONPath string ('$.id'). On MySQL every lookup by message key (findMessages, edit/delete/update by message id, Chatwoot sync, the Meta channel) fails Prisma validation withArgument `path`: Invalid value provided. Expected String.A small
jsonPath(field)helper (src/utils/jsonPath.ts) returns'$.field'on MySQL and['field']otherwise, and the 28 filters use it.2.
Labelhas no(labelId, instanceId)unique key on MySQLThe Baileys label sync upserts by
labelId_instanceId. The PostgreSQL schema has had that key since20240813003116_make_label_unique_for_instance, but the MySQL schema and migrations never got it. The MySQL Prisma client therefore rejects the upsert at runtime withUnknown argument `labelId_instanceId`, andtsc --noEmitfails with two TS2353 errors inwhatsapp.baileys.service.tswhen the client is generated from the MySQL schema. The PR adds@@unique([labelId, instanceId])and a migration that creates the index.3. MySQL chat label updates lose or duplicate labels
removeLabel: when the label is not on the chat,JSON_SEARCHreturnsNULL, soJSON_REMOVEreturnsNULL, and theCOALESCEthen replaces the chat's labels with[]. Every other label on the chat is wiped.addLabel:JSON_ARRAY_APPENDappends even when the label is already present, so repeated label events duplicate it. The PostgreSQL branch deduplicates.Both now check
JSON_CONTAINSfirst.JSON_SEARCHuses an escape character, so a label id containing%or_is matched literally.🔗 Related Issue
Related to #2344 (MySQL errors on v2.3.6). PR #2769 touches the same area against
main; this one is scoped to what is still missing ondevelopand targetsdevelopas described in CONTRIBUTING.🧪 Type of Change
🧪 Testing
On MySQL 8.4, against a fresh database migrated with
prisma/mysql-migrations(including the new migration):@prisma/adapter-mariadb), with thedevelopschema and then with this PR's schema:key: { path: ['id'] }fails withExpected Stringon both;path: '$.id'(whatjsonPathreturns) matches the row.label.upsert({ where: { labelId_instanceId } })fails withUnknown argumentondevelopand succeeds with this PR.%(matched literally), remove fromNULLlabels.tsc --noEmit: 2 errors ondevelopwith the MySQL client, 0 with this PR for both the MySQL and the PostgreSQL client.eslintpasses on the changed files.✅ Checklist
📝 Additional Notes
The new migration fails if an existing MySQL install already has duplicate
(labelId, instanceId)rows, the same way the PostgreSQL migration would. Labels are re-synced from WhatsApp, so removing duplicates before upgrading is safe.Summary by Sourcery
Fix MySQL message JSON filtering, label synchronization, and chat label updates without changing PostgreSQL behavior.
Bug Fixes:
Enhancements: