Skip to content

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

@waptik

Description

@waptik

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/pentagon@v0.1.3/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?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions