evolution-api icon indicating copy to clipboard operation
evolution-api copied to clipboard

fix(prisma): add unique constraint to Chat model in Postgres

Open msantosjader opened this issue 2 months ago โ€ข 1 comments

๐Ÿ“‹ Description

Fixes a critical bug affecting PostgreSQL users where label operations fail with PrismaClientKnownRequestError (Code 42P10).

The issue occurs because addLabel and removeLabel methods rely on an ON CONFLICT clause that requires a unique constraint on (instanceId, remoteJid). This PR adds the missing @@unique constraint to the Chat model in postgresql-schema.prisma and includes the necessary SQL migration to align behavior with MySQL.

๐Ÿ”— Related Issue

Closes #2152

๐Ÿงช Type of Change

  • [x] ๐Ÿ› 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

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

Manually verified by applying the migration to a clean PostgreSQL container. Confirmed via psql that the unique index "Chat_instanceId_remoteJid_key" was successfully created in the database structure.

โœ… Checklist

  • [x] My code follows the project's style guidelines
  • [x] 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
  • [x] My changes generate no new warnings
  • [x] I have manually tested my changes thoroughly
  • [x] I have verified the changes work with different scenarios
  • [ ] Any dependent changes have been merged and published

๐Ÿ“ Additional Notes

The migration file was generated using prisma migrate dev --create-only and populated manually with the specific CREATE UNIQUE INDEX command. This ensures a clean migration path without generating unnecessary SQL for existing tables.

Summary by Sourcery

Add a unique constraint for Chat records in the PostgreSQL schema to align behavior with other databases and prevent label operation failures.

Bug Fixes:

  • Resolve PostgreSQL label operation failures caused by missing uniqueness on Chat instance and remote JID combinations.

Build:

  • Introduce a Prisma PostgreSQL migration that creates a unique index on Chat(instanceId, remoteJid) to enforce the new constraint.

msantosjader avatar Nov 22 '25 00:11 msantosjader

Reviewer's guide (collapsed on small PRs)

Reviewer's Guide

Adds a missing unique constraint on (instanceId, remoteJid) for the Chat model in the PostgreSQL Prisma schema and introduces a corresponding migration to create the unique index in the database, aligning Postgres behavior with MySQL and fixing ON CONFLICT label operations.

Sequence diagram for label operations using ON CONFLICT with the new Chat unique index

sequenceDiagram
  actor "User" as User
  participant "API Server" as Api
  participant "Prisma Client" as Prisma
  participant "PostgreSQL" as Postgres

  "User" ->> "API Server": "Request to add or remove label on chat (instanceId, remoteJid)"
  "API Server" ->> "Prisma Client": "call addLabel/removeLabel(chatId, labelId)"
  "Prisma Client" ->> "PostgreSQL": "INSERT label mapping WITH ON CONFLICT (instanceId, remoteJid) DO UPDATE"
  "PostgreSQL" ->> "PostgreSQL": "Use unique index \"Chat_instanceId_remoteJid_key\" to resolve conflict"
  "PostgreSQL" -->> "Prisma Client": "Successful upsert of label mapping (no 42P10 error)"
  "Prisma Client" -->> "API Server": "Operation result (success)"
  "API Server" -->> "User": "Label operation completed successfully"

Entity relationship diagram for Chat model with composite unique constraint

erDiagram
  Chat {
    string id
    string instanceId
    string remoteJid
    string otherChatFields
    string UNIQUE_instanceId_remoteJid
  }

File-Level Changes

Change Details Files
Add unique composite constraint for Chat to support ON CONFLICT in label operations on PostgreSQL.
  • Update PostgreSQL Prisma schema to declare a @@unique constraint on the Chat model for (instanceId, remoteJid).
  • Introduce a Prisma migration that creates a unique index Chat_instanceId_remoteJid_key on the Chat table for (instanceId, remoteJid).
prisma/postgresql-schema.prisma
prisma/postgresql-migrations/20251122003044_add_chat_instance_remotejid_unique/migration.sql

Assessment against linked issues

Issue Objective Addressed Explanation
https://github.com/EvolutionAPI/evolution-api/issues/2152 Add a UNIQUE constraint (or unique index) on ("instanceId", "remoteJid") to the Postgres "Chat" table so that the ON CONFLICT clause used by addLabel/removeLabel works correctly. โœ…
https://github.com/EvolutionAPI/evolution-api/issues/2152 Update the Prisma/Postgres schema and migrations so that the Chat model enforces uniqueness on (instanceId, remoteJid) and can be applied via Prisma tooling. โœ…

Possibly linked issues

  • #2152: PR adds the unique constraint on Chat(instanceId, remoteJid) that the issue identifies as missing and required.
  • #2152: PR implements the suggested unique constraint and migration to fix the Chat upsert 42P10 error in Postgres.
  • #2152: PR adds required unique constraint on Chat to resolve the PostgreSQL ON CONFLICT 42P10 label error.

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

  • Contact our support team for questions or feedback.
  • Visit our documentation for detailed guides and information.
  • Keep in touch with the Sourcery team by following us on X/Twitter, LinkedIn or GitHub.

sourcery-ai[bot] avatar Nov 22 '25 00:11 sourcery-ai[bot]