Files
epess-web-backend/src/MeetingRoom/meetingroom.schema.ts
2024-12-20 18:30:50 +07:00

224 lines
7.1 KiB
TypeScript

import { Inject, Injectable, Logger } from '@nestjs/common'
import { Pothos, PothosRef, PothosSchema, SchemaBuilderToken } from '@smatch-corp/nestjs-pothos'
import { Builder, SchemaContext } from 'src/Graphql/graphql.builder'
import { LiveKitService } from 'src/LiveKit/livekit.service'
import { MinioService } from 'src/Minio/minio.service'
import { PrismaService } from 'src/Prisma/prisma.service'
@Injectable()
export class MeetingRoomSchema extends PothosSchema {
constructor(
@Inject(SchemaBuilderToken) private readonly builder: Builder,
private readonly prisma: PrismaService,
private readonly livekitService: LiveKitService,
private readonly minioService: MinioService,
) {
super()
}
@PothosRef()
meetingRoom() {
return this.builder.prismaObject('MeetingRoom', {
fields: (t) => ({
id: t.exposeID('id'),
collaborationSessionId: t.exposeString('collaborationSessionId'),
collaborationSession: t.relation('collaborationSession'),
collaborators: t.relation('collaborators'),
createdAt: t.expose('createdAt', { type: 'DateTime' }),
updatedAt: t.expose('updatedAt', { type: 'DateTime' }),
recordUrl: t.string({
nullable: true,
resolve: async (meetingRoom) => {
return await this.minioService.getRoomRecordUrl(meetingRoom.id)
},
}),
}),
})
}
@PothosRef()
meetingRoomJoinInfo() {
return this.builder.simpleObject('MeetingRoomJoinInfo', {
fields: (t) => ({
id: t.string({
description: 'The ID of the meeting room.',
}),
token: t.string({
description: 'The token to join the meeting room.',
}),
serverUrl: t.string({
description: 'The URL of the server.',
}),
}),
})
}
@PothosRef()
meetingRoomCollaborator() {
return this.builder.prismaObject('MeetingRoomCollaborator', {
fields: (t) => ({
id: t.exposeID('id'),
meetingRoomId: t.exposeString('meetingRoomId'),
meetingRoom: t.relation('meetingRoom'),
userId: t.exposeString('userId'),
user: t.relation('user'),
}),
})
}
@Pothos()
init(): void {
this.builder.queryFields((t) => ({
// get meeting room by collaboration session id if exist or create new one
meetingRoom: t.prismaField({
type: this.meetingRoom(),
args: {
scheduleDateId: t.arg.string({
required: true,
}),
},
resolve: async (_query, _parent, args, _ctx: SchemaContext) => {
const collaborationSession = await this.prisma.collaborationSession.findUnique({
where: {
scheduleDateId: args.scheduleDateId,
},
})
if (!collaborationSession) {
throw new Error('Collaboration session not found')
}
const meetingRoom = await this.prisma.meetingRoom.findUnique({
where: {
collaborationSessionId: collaborationSession.id,
},
})
if (meetingRoom) {
return meetingRoom
}
return await this.prisma.meetingRoom.create({
data: {
collaborationSessionId: collaborationSession.id,
},
})
},
}),
// get meeting room info by room id and check if user is collaborator of collaboration session then create new token and return it,
// if not collaborator then throw error
meetingRoomJoinInfo: t.field({
type: this.meetingRoomJoinInfo(),
args: {
collaborationSessionId: t.arg.string({
required: true,
}),
},
resolve: async (_, args, ctx: SchemaContext) => {
if (!ctx.me) {
throw new Error('Unauthorized')
}
const meetingRoom = await this.prisma.meetingRoom.findUnique({
where: { collaborationSessionId: args.collaborationSessionId },
})
if (!meetingRoom) {
throw new Error('Meeting room not found')
}
// check if user is collaborator of collaboration session
const collaborationSession = await this.prisma.collaborationSession.findUnique({
where: { id: meetingRoom.collaborationSessionId },
})
if (!collaborationSession) {
throw new Error('Collaboration session not found')
}
if (!collaborationSession.collaboratorsIds.includes(ctx.me.id)) {
throw new Error('User is not collaborator')
}
// create new token
const token = await this.livekitService.createToken(ctx.me, meetingRoom.id)
return {
id: meetingRoom.id,
token,
serverUrl: this.livekitService.getServerUrl(),
}
},
}),
interviewJoinInfo: t.field({
type: this.meetingRoomJoinInfo(),
args: {
scheduleId: t.arg.string({
required: true,
}),
},
resolve: async (_, args, ctx: SchemaContext) => {
if (!ctx.me) {
throw new Error('Unauthorized')
}
const token = await this.livekitService.createToken(ctx.me, args.scheduleId)
return {
id: args.scheduleId,
token,
serverUrl: this.livekitService.getServerUrl(),
}
},
}),
}))
this.builder.mutationFields((t) => ({
createMeetingRoom: t.prismaField({
type: this.meetingRoom(),
args: {
input: t.arg({
type: this.builder.generator.getCreateInput('MeetingRoom', [
'id',
'createdAt',
'updatedAt',
'collaborators',
]),
required: true,
}),
},
resolve: async (query, _parent, args, ctx: SchemaContext) => {
if (!ctx.me) {
throw new Error('Unauthorized')
}
return await this.prisma.meetingRoom.create({
...query,
data: args.input,
})
},
}),
updateMeetingRoomCollaborators: t.prismaField({
type: this.meetingRoom(),
args: {
meetingRoomId: t.arg.string({
required: true,
}),
addCollaborators: t.arg.stringList({
required: false,
}),
removeCollaborators: t.arg.stringList({
required: false,
}),
},
resolve: async (query, _parent, args, ctx: SchemaContext) => {
if (!ctx.me) {
throw new Error('Unauthorized')
}
return await this.prisma.meetingRoom.update({
...query,
where: {
id: args.meetingRoomId,
},
data: {
collaborators: {
createMany: {
data: args.addCollaborators ? args.addCollaborators.map((id) => ({ userId: id })) : [],
},
deleteMany: {
userId: {
in: args.removeCollaborators || [],
},
},
},
},
})
},
}),
}))
}
}