pentagon
pentagon copied to clipboard
[Help]: How do i achieve this type of relation?
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?