pentagon icon indicating copy to clipboard operation
pentagon copied to clipboard

[Help]: How do i achieve this type of relation?

Open waptik opened this issue 11 months ago • 0 comments

Let's say i have the following prisma schema and queries, how do i achieve it with pentagon at this current stage?

Prisma schema

model User {
  id            Int    @id 
  firstName          String
  username         String?   @unique
  lastName         String?

  projects       ProjectUsers[]
  createdAt      DateTime       @default(now())
  updatedAt      DateTime      @updateAt
}

model Project {
  id                 String          @id @default(uuid())
  name           String

  users           ProjectUsers[]
  plan             String          @default("free")
  

  createdAt          DateTime        @default(now())
  updatedAt          DateTime        @updatedAt
}

model ProjectUsers {
  id        String   @id @default(uuid())
  role      String   @default("member")
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt
  user      User     @relation(fields: [userId], references: [id], onDelete: Cascade)
  userId    String
  project   Project  @relation(fields: [projectId], references: [id], onDelete: Cascade)
  projectId String

  @@unique([userId, projectId])
  @@index([projectId])
}
Queries
// get all projects
const projects = await prisma.project.findMany({
        where: {
          users: {
            some: {
              userId: session.user.id,
            },
          },
        },
        include: {
          domains: true,
        },
      });
      console.log(projects);

// get all members of a project
const users = await prisma.projectUsers.findMany({
      where: {
        projectId: project.id,
      },
      select: {
        user: {
          select: {
            id: true,
            name: true,
          },
        },
        createdAt: true,
      },
    });
console.log(users)

// create a project and link to a user
 const newProject = await prisma.project.create({
          data: {
            name,
            slug,
            users: {
              create: {
                userId: session.user.id,
                role: "owner",
              },
            },
          },
        }),

So here are model definitions so far:

Pentagon model definitions
import { createPentagon } from "https://deno.land/x/[email protected]/mod.ts";
import { z } from "zod";
import { kv } from "$utils/db/kv.ts";

const WithDefautTimestamps = z.object({
  createdAt: z
    .string()
    .datetime()
    .default(() => new Date().toISOString()),
  updatedAt: z
    .string()
    .datetime()
    .default(() => new Date().toISOString())
    .nullable()
    .nullable(),
});

const WithDefaultId = z.object({
  id: z
    .string()
    .uuid()
    .default(() => crypto.randomUUID())
    .describe("primary"),
});

const UserModel = z
  .object({
    id: z.number().describe("primary"),
    firstName: z.string(),
    lastName: z.string().optional(),
    username: z.string().describe("unique").optional(),
    role: z.enum(["admin", "user", "root"]).default("user"),
  })
  .merge(WithDefautTimestamps);

const ProjectModel = WithDefaultId.extend({
  name: z.string(),
  description: z.string().optional(),
  plan: z.string().default("free"),
}).merge(WithDefautTimestamps);

const ProjectUserModel = WithDefaultId.extend({
  role: z.enum(["owner", "member"]).default("member"),

  // relations
  projectId: z.string().uuid().describe("unique"),
  userId: z.number().describe("unique"),
}).merge(WithDefautTimestamps);

export const pentagon = createPentagon(kv, {
  users: {
    schema: UserModel,
    relations: {
      projects: ["projectUsers", [ProjectUsersModel], "??", "??"], // how to fix "?"
    },
  },
  projects: {
    schema: ProjectModel,
    relations: {
      // name: [relation name, schema, local key, foreign key]
      users: ["projectUsers", [ProjectUsersModel], "??", "??"], // how to fix "?"
    },
  },
  projectUsers: {
    schema: ProjectUsersModel,
    relations: {
      project: ["project", ProjectModel, "projectId", "id"],
      user: ["user", UserModel, "userId", "id"],
    },
  },
});

So looking at the prisma schema definition and the model definitions using zod, how do i properly define the relations between users, projects and projectUsers and easily replicate the queries?

waptik avatar Jul 24 '23 16:07 waptik