update manyyyyyyyyy

This commit is contained in:
2024-11-22 15:06:49 +07:00
parent 8eec1bed55
commit d8a3894aba
10 changed files with 272 additions and 101 deletions

View File

@@ -1,9 +1,9 @@
import { Module } from '@nestjs/common'
import { UserSchema } from './user.schema'
import { MessageModule } from '../Message/message.module'
import { ChatroomModule } from '../ChatRoom/chatroom.module'
@Module({
imports: [MessageModule],
imports: [MessageModule, ChatroomModule],
providers: [UserSchema],
exports: [UserSchema],
})

View File

@@ -1,33 +1,26 @@
import { Inject, Injectable, Logger } from '@nestjs/common'
import { Pothos, PothosRef, PothosSchema, SchemaBuilderToken } from '@smatch-corp/nestjs-pothos'
import {
Pothos,
PothosRef,
PothosSchema,
SchemaBuilderToken,
} from '@smatch-corp/nestjs-pothos'
import { Builder, SchemaContext } from '../Graphql/graphql.builder'
import { PrismaService } from '../Prisma/prisma.service'
import { clerkClient } from '@clerk/express'
import { UnauthorizedException } from '@nestjs/common'
import { MailService } from '../Mail/mail.service'
import { MessageSchema } from 'src/Message/message.schema'
import { ChatRoom, Message, MessageContextType, MessageType, Role } from '@prisma/client'
import {
ChatRoom,
Message,
MessageContextType,
MessageType,
Role,
} from '@prisma/client'
import { PubSubEvent } from 'src/common/pubsub/pubsub-event'
import { DateTimeUtils } from 'src/common/utils/datetime.utils'
import { JsonValue } from '@prisma/client/runtime/library'
import { z } from 'zod'
type UserWithChatRooms = {
name: string
id: string
email: string
phoneNumber: string | null
bankBin: string | null
bankAccountNumber: string | null
packageValue: number
role: Role
avatarUrl: string | null
createdAt: Date
updatedAt: Date
customerChatRoom?: ChatRoom[]
mentorChatRoom?: ChatRoom[]
}
import { ChatroomSchema } from '../ChatRoom/chatroom.schema'
@Injectable()
export class UserSchema extends PothosSchema {
constructor(
@@ -35,6 +28,7 @@ export class UserSchema extends PothosSchema {
private readonly prisma: PrismaService,
private readonly mailService: MailService,
private readonly messageSchema: MessageSchema,
private readonly chatRoomSchema: ChatroomSchema,
) {
super()
}
@@ -128,6 +122,30 @@ export class UserSchema extends PothosSchema {
})
}
@PothosRef()
recentChatActivity() {
return this.builder.simpleObject('RecentChatActivity', {
fields: (t) => ({
chatRoom: t.field({
type: this.chatRoomSchema.chatRoom(),
description: 'The chat room.',
}),
lastActivity: t.field({
type: 'DateTime',
description: 'The last activity of the chat room.',
}),
sender: t.field({
type: this.user(),
description: 'The sender of the message.',
}),
message: t.field({
type: this.messageSchema.message(),
description: 'The last message of the chat room.',
}),
}),
})
}
// Query section
@Pothos()
init(): void {
@@ -160,40 +178,73 @@ export class UserSchema extends PothosSchema {
}),
me: t.prismaField({
description: 'Retrieve the current user in context.',
type: this.user() || 'Json',
args: {
includeChatRoom: t.arg({ type: 'Boolean', required: false }),
},
type: this.user(),
resolve: async (_query, _root, _args, ctx) => {
if (ctx.isSubscription) {
throw new Error('Not allowed')
}
let user = ctx.http.me as UserWithChatRooms
return ctx.http.me
},
}),
if (!user?.name) {
throw new Error('User not found')
}
if (_args.includeChatRoom) {
const customerChatRoom = await this.prisma.chatRoom.findMany({
where: {
OR: [{ customerId: ctx.http.me?.id }, { mentorId: ctx.http.me?.id }],
},
distinct: ['id'],
orderBy: {
lastActivity: 'desc',
},
})
user = {
...user,
customerChatRoom,
}
}
return user
recentChatActivity: t.field({
description: 'Retrieve the recent chat activity of the current user.',
type: [this.recentChatActivity()],
args: {
take: t.arg({ type: 'Int', required: false }),
},
resolve: async (_parent, args, ctx) => {
if (ctx.isSubscription) throw new Error('Not allowed')
const me = ctx.http.me
if (!me) throw new Error('User not found')
// get chat rooms that the user is a part of
const chatRooms = await this.prisma.chatRoom.findMany({
where: {
OR: [{ customerId: me.id }, { mentorId: me.id }],
},
orderBy: {
lastActivity: 'desc',
},
take: args.take ?? 10,
})
// get the last message for each chat room
const lastMessages = await Promise.all(
chatRooms.map(async (chatRoom) => {
const lastMessage = await this.prisma.message.findFirst({
where: {
chatRoomId: chatRoom.id,
},
orderBy: {
sentAt: 'desc',
},
})
if (!lastMessage) return null
const sender = lastMessage.senderId
? await this.prisma.user.findUnique({
where: { id: lastMessage.senderId },
})
: undefined
return {
chatRoom: chatRoom,
lastActivity: lastMessage.sentAt,
sender: sender,
message: lastMessage,
}
}),
)
return lastMessages.filter((msg) => msg !== null)
},
}),
users: t.prismaField({
description: 'Retrieve a list of users with optional filtering, ordering, and pagination.',
description:
'Retrieve a list of users with optional filtering, ordering, and pagination.',
type: [this.user()],
args: this.builder.generator.findManyArgs('User'),
resolve: async (query, _root, args) => {
@@ -325,9 +376,10 @@ export class UserSchema extends PothosSchema {
}
const buffer = Buffer.concat(chunks)
const { id: userId, imageUrl } = await clerkClient.users.updateUserProfileImage(id, {
file: new Blob([buffer]),
})
const { id: userId, imageUrl } =
await clerkClient.users.updateUserProfileImage(id, {
file: new Blob([buffer]),
})
await this.prisma.user.update({
where: { id: userId },
data: {
@@ -405,9 +457,14 @@ export class UserSchema extends PothosSchema {
throw new Error(`User ${args.email} not found`)
}
// send email
await this.mailService.sendTemplateEmail([args.email], 'Thông báo chọn lựa quản trị viên cho người điều hành', 'ModeratorInvitation', {
USER_NAME: user.name,
})
await this.mailService.sendTemplateEmail(
[args.email],
'Thông báo chọn lựa quản trị viên cho người điều hành',
'ModeratorInvitation',
{
USER_NAME: user.name,
},
)
return 'Invited'
})
},
@@ -444,7 +501,10 @@ export class UserSchema extends PothosSchema {
},
})
// publish message
await ctx.http.pubSub.publish(`${PubSubEvent.NEW_MESSAGE}.${message.recipientId}`, message)
await ctx.http.pubSub.publish(
`${PubSubEvent.NEW_MESSAGE}.${message.recipientId}`,
message,
)
return message
},
}),
@@ -459,7 +519,9 @@ export class UserSchema extends PothosSchema {
const {
websocket: { pubSub },
} = ctx
return pubSub.asyncIterator([`${PubSubEvent.NEW_MESSAGE}.${ctx.websocket.me?.id}`]) as unknown as AsyncIterable<Message>
return pubSub.asyncIterator([
`${PubSubEvent.NEW_MESSAGE}.${ctx.websocket.me?.id}`,
]) as unknown as AsyncIterable<Message>
},
resolve: async (payload: Message) => payload,
}),