Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
waptik opened this issue Jul 24, 2023 · 0 comments
Open

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

waptik opened this issue Jul 24, 2023 · 0 comments

Comments

@waptik
Copy link
Contributor

waptik commented Jul 24, 2023

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?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant