224 lines
7.1 KiB
TypeScript
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 || [],
|
|
},
|
|
},
|
|
},
|
|
},
|
|
})
|
|
},
|
|
}),
|
|
}))
|
|
}
|
|
}
|