- 
          
- 
                Notifications
    You must be signed in to change notification settings 
- Fork 126
Closed
Labels
Description
Description and expected behavior
Suppose you have an m-to-n relation: OrganizationRole <- OrganizationRolePrivilege -> Privilege.  The Organization role is a delegate further breaking down into 2 concrete models: SystemDefinedRole and CustomOrganizationRole:
model OrganizationRole {
  id              Int @id @default(autoincrement())
  name        String
  rolePrivileges  OrganizationRolePrivilege[]
  type            String
  @@delegate(type)
}
// roles common to all orgs, defined once
model SystemDefinedRole extends OrganizationRole {
  name String @unique
}
// roles specifc to each org
model CustomOrganizationRole extends OrganizationRole {
  name String
  organizationId Int
  organization   Organization @relation(fields: [organizationId], references: [id])
  @@unique([organizationId, name])
  @@index([organizationId])
}
model OrganizationRolePrivilege {
  organizationRoleId Int
  privilegeId        Int
  organizationRole   OrganizationRole @relation(fields: [organizationRoleId], references: [id])
  privilege          Privilege        @relation(fields: [privilegeId], references: [id])
  @@id([organizationRoleId, privilegeId])
}
model Privilege {
  id                  Int @id @default(autoincrement())
  name                String // e.g. "org:manage"
  orgRolePrivileges   OrganizationRolePrivilege[]
  @@unique([name])
}
With the Privilege table is already preloaded with all privileges, it's not possible to create a new concrete Role and connect it to existing privileges.
Below are a few attempts but unsuccessful:
Attempt 1: Connecting by foreign key
await db.systemDefinedRole.create({
    data: {
        name: 'Admin',
        rolePrivileges: {
            create: [
                {
                    privilegeId: 1,
                    // ✖ currently requires a organizationRoleId but organizationRole not created yet
                    organizationRoleId:1
                }
            ],
        },
    },
});Attempt 2: Connecting by a relation name
await db.systemDefinedRole.create({
    data: {
      name: 'Admin',
      rolePrivileges: {
        create: [
          {
            // ✖ privilege relation not exposed
            privilege: {
              connect: { id: 1 },
            },
          },
        ],
      },
    },
  })Environment (please complete the following information):
- ZenStack version: 2.11.6
- Prisma version: 5.22.0
- Database type: Postgresql
Additional context
See related Discord thread.
With raw Prisma, this is achievable in 2 different ways. Both of which expose the privilege relation to connect to:
const db = await prismaEnhanced({ bypassPolicy: true})
  const privileges = await db.privilege.createMany({
    data: [...orgPrivileges, ...studyPrivileges],
  })
// 1. Using raw prisma with the OrganizationRole delegate model
await prisma.organizationRole.create({
    data: {
      // name: 'Owner',
      description:
        'Admin access',
      type: 'SystemDefinedRole',
      delegate_aux_systemDefinedRole: {
        create: { name: 'Admin' },
      },
      rolePrivileges: {
        create: [
          {
            privilege: {
              connect: { id: 1 },
            },
          },
        ],
      },
    },
  })
// 2: Using raw prisma with the SystemDefinedRole concrete model
  await prisma.systemDefinedRole.create({
    data: {
      name: 'Admin',
      delegate_aux_organizationRole: {
        create: {
          description:
            'Admin access',
          type: 'SystemDefinedRole',
          rolePrivileges: {
            create: [
              {
                privilege: {
                  connect: { id: 1 },
                },
              },
            ],
          },
        },
      },
    },
  })jiashengguo and araj-dev