Skip to main content
Glama
prisma.ts5.57 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