import { PrismaClient } from '@prisma/client'; import { AuthenticationError, ForbiddenError } from 'apollo-server-express'; import { PubSub, withFilter } from 'graphql-subscriptions'; const prisma = new PrismaClient(); const pubsub = new PubSub(); export const MESSAGE_ADDED = 'MESSAGE_ADDED'; export const messageResolvers = { Query: { messages: async (_: any, { roomId }: { roomId: string }, context: any) => { if (!context.userId) { throw new AuthenticationError('You must be logged in to view messages'); } // Check if user is a member of the room const room = await prisma.room.findUnique({ where: { id: roomId }, include: { members: true }, }); if (!room) { throw new ForbiddenError('Room not found'); } const isMember = room.members.some( (member: { id: string }) => member.id === context.userId ); if (!isMember) { throw new ForbiddenError('You are not a member of this room'); } return prisma.message.findMany({ where: { roomId }, orderBy: { createdAt: 'asc' }, }); }, }, Mutation: { sendMessage: async ( _: any, { content, roomId }: { content: string; roomId: string }, context: any ) => { if (!context.userId) { throw new AuthenticationError( 'You must be logged in to send a message' ); } // Check if user is a member of the room const room = await prisma.room.findUnique({ where: { id: roomId }, include: { members: true }, }); if (!room) { throw new ForbiddenError('Room not found'); } const isMember = room.members.some( (member: { id: string }) => member.id === context.userId ); if (!isMember) { throw new ForbiddenError('You are not a member of this room'); } const message = await prisma.message.create({ data: { content, user: { connect: { id: context.userId }, }, room: { connect: { id: roomId }, }, }, include: { user: true, room: true, }, }); pubsub.publish(MESSAGE_ADDED, { messageAdded: message, roomId }); return message; }, }, Subscription: { messageAdded: { subscribe: withFilter( () => pubsub.asyncIterator([MESSAGE_ADDED]), (payload, variables) => { return payload.roomId === variables.roomId; } ), }, }, Message: { user: async (parent: any) => { return prisma.user.findUnique({ where: { id: parent.userId }, }); }, room: async (parent: any) => { return prisma.room.findUnique({ where: { id: parent.roomId }, }); }, }, };