Skip to main content
Glama
prisma.ts5.22 kB
// ============================================ // Prisma Client Instance - db.ts // ============================================ import { PrismaClient } from "@prisma/client"; const globalForPrisma = globalThis as unknown as { prisma: PrismaClient | undefined; }; export const prisma = globalForPrisma.prisma ?? new PrismaClient({ log: process.env.NODE_ENV === "development" ? ["query", "error", "warn"] : ["error"], }); if (process.env.NODE_ENV !== "production") globalForPrisma.prisma = prisma; // ============================================ // Schema (schema.prisma) // ============================================ /* generator client { provider = "prisma-client-js" } datasource db { provider = "postgresql" // or mysql, sqlite, sqlserver url = env("DATABASE_URL") } model User { id Int @id @default(autoincrement()) email String @unique name String password String // Hashed role Role @default(USER) posts Post[] profile Profile? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt @@index([email]) } model Profile { id Int @id @default(autoincrement()) bio String? userId Int @unique user User @relation(fields: [userId], references: [id], onDelete: Cascade) } model Post { id Int @id @default(autoincrement()) title String content String? published Boolean @default(false) viewCount Int @default(0) authorId Int author User @relation(fields: [authorId], references: [id]) categories Category[] createdAt DateTime @default(now()) updatedAt DateTime @updatedAt @@index([authorId]) } model Category { id Int @id @default(autoincrement()) name String @unique posts Post[] } enum Role { USER ADMIN } */ // ============================================ // Services / Repositories // ============================================ export const userService = { async findByEmail(email: string) { return prisma.user.findUnique({ where: { email }, include: { profile: true }, }); }, async create(data: { email: string; name: string; password: string }) { return prisma.user.create({ data: { ...data, profile: { create: { bio: "New user" }, }, }, }); }, async getFeed(userId: number) { // Get posts from authors followed by user (example logic) return prisma.post.findMany({ where: { published: true, authorId: { not: userId }, // Exclude own posts }, include: { author: { select: { name: true, email: true }, }, _count: { select: { categories: true }, }, }, orderBy: { createdAt: "desc" }, take: 20, }); }, }; export const postService = { async create(userId: number, title: string, content?: string) { return prisma.post.create({ data: { title, content, authorId: userId, }, }); }, async publish(postId: number, userId: number) { // Verify ownership and update const post = await prisma.post.findUnique({ where: { id: postId } }); if (!post) throw new Error("Post not found"); if (post.authorId !== userId) throw new Error("Not authorized"); return prisma.post.update({ where: { id: postId }, data: { published: true }, }); }, async delete(postId: number, userId: number) { return prisma.post.deleteMany({ where: { id: postId, authorId: userId, // Ensure ownership }, }); }, }; // ============================================ // Transaction Example // ============================================ export async function transferOwnership(postId: number, newAuthorId: number) { return prisma.$transaction(async (tx) => { const post = await tx.post.findUniqueOrThrow({ where: { id: postId } }); // Log the transfer console.log(`Transferring post ${post.id} to user ${newAuthorId}`); const updated = await tx.post.update({ where: { id: postId }, data: { authorId: newAuthorId }, }); return updated; }); } // ============================================ // Pagination Helper // ============================================ export async function getPostsPaginated(cursor?: number, limit = 10) { return prisma.post.findMany({ take: limit, skip: cursor ? 1 : 0, // Skip the cursor itself cursor: cursor ? { id: cursor } : undefined, orderBy: { id: "desc" }, where: { published: true }, }); } // ============================================ // Middleware Example (Soft Delete) // ============================================ /* prisma.$use(async (params, next) => { // Check incoming query type if (params.model == 'Post' && params.action == 'delete') { // Change action to an update params.action = 'update' params.args['data'] = { deleted: true } } return next(params) }) */ // ============================================ // Clean Shutdown // ============================================ export async function disconnect() { await prisma.$disconnect(); }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/millsydotdev/Code-MCP'

If you have feedback or need assistance with the MCP directory API, please join our Discord server