zenstackhq / zenstack

Fullstack TypeScript toolkit that enhances Prisma ORM with flexible Authorization layer for RBAC/ABAC/PBAC/ReBAC, offering auto-generated type-safe APIs and frontend hooks.
https://zenstack.dev
MIT License
2.07k stars 88 forks source link

Zenstack having problems with upserting relations with compound keys #1271

Closed CollinKempkes closed 5 months ago

CollinKempkes commented 5 months ago

Description and expected behavior The problem is that zenstack is having some kind of problem of upserting relations when the where part of the upsert is using a compound/ unique key. With an unenhanced client it works as expected. Also when using the normal PrimaryKey it also work as expected, just in this scenario using unique keys is broken.

To recreate this behaviour use this code:

import "../../../prisma/zmodel/auth/user.zmodel"

model Test {
  id String @id @default(dbgenerated("uuid_generate_v4()")) @db.Uuid
  linkingTable LinkingTable[]
  key String @default('test')
  locale String @default('EN')

  @@schema("public")
  @@map("test")

  @@unique([key, locale])
  @@allow("all", true)
}

model LinkingTable {
  test_id String @db.Uuid
  test Test @relation(fields: [test_id], references: [id])

  another_test_id String @db.Uuid
  another_test AnotherTest @relation(fields: [another_test_id], references: [id])

  @@id([test_id, another_test_id])
  @@map("__linking_table")
  @@schema("public")

  @@allow("all", true)
}

model AnotherTest {
  id String @id @default(dbgenerated("uuid_generate_v4()")) @db.Uuid
  status String
  linkingTable LinkingTable[]

  @@schema("public")
  @@map("another_test")

  @@allow("all", true)
}
import { PrismaClient } from '@equitybytes/nest-prisma';
import { enhance } from '@zenstackhq/runtime';

describe('test', () => {
  const enhancedPrisma = enhance(new PrismaClient());
  it('should be true', async () => {
    const enhancedPrisma = enhance(new PrismaClient());

    const test = await enhancedPrisma.test.create({
      data: {
        key: 'hello',
      },
    });
    const anotherTest = await enhancedPrisma.anotherTest.create({
      data: {
        status: 'available',
      },
    });

    await enhancedPrisma.test.upsert({
      where: {
        key_locale: {
          key: test.key,
          locale: test.locale,
        },
      },
      create: {
        linkingTable: {
          create: {
            another_test_id: anotherTest.id,
          },
        },
      },
      update: {
        linkingTable: {
          create: {
            another_test_id: anotherTest.id,
          },
        },
      },
    });
  });
});

The responding error message is:

Error calling enhanced Prisma method `upsert`: 
Invalid `prisma.test.findUniqueOrThrow()` invocation:

    {
      select: {
        id: true
      },
    + where: {
    +   id: String,
    +   key_locale: TestKeyLocaleCompoundUniqueInput,
    +   AND: TestWhereInput | TestWhereInput[],
    +   OR: TestWhereInput[],
    +   NOT: TestWhereInput | TestWhereInput[],
    +   key: StringFilter | String,
    +   locale: StringFilter | String,
    +   linkingTable: LinkingTableListRelationFilter
    + }
    }

    Argument `where` is missing.

Debug log also says:

[Nest] 53375  - 04/19/2024, 4:18:36 PM     LOG [Prisma] Duration: 1ms
  console.log
    prisma:info [policy] `findUniqueOrThrow` LinkingTable: looking up upstream entity of Test, { where: undefined, select: { id: true } }

      at Object.Ku (../../node_modules/@prisma/client/runtime/library.js:22:432)

[Nest] 53375  - 04/19/2024, 4:18:36 PM   DEBUG [Prisma] Message: [policy] `findUniqueOrThrow` LinkingTable: looking up upstream entity of Test, { where: undefined, select: { id: true } }
[Nest] 53375  - 04/19/2024, 4:18:36 PM   DEBUG [Prisma] Target: zenstack
[Nest] 53375  - 04/19/2024, 4:18:36 PM   DEBUG [Prisma] Timestamp: Fri Apr 19 2024 16:18:36 GMT+0200 (Central European Summer Time)

Environment:

ymc9 commented 5 months ago

Thanks @CollinKempkes . I'm able to reproduce it. Will make a fix soon.

ymc9 commented 5 months ago

Hi @CollinKempkes , could you check if the new 1.12.4 release resolves the issue for you?

mattgstevens commented 5 months ago

Hi @ymc9 , following up as Collin is afk for the next weeks.

This did fix the issue, thank you for the release :rainbow:

ymc9 commented 5 months ago

Thank you for the confirmation!