feat: add Me module with service and controller for user-specific class and room management
This commit is contained in:
parent
3577925932
commit
d66a2c2c35
@ -28,15 +28,16 @@
|
||||
"@nestjs/platform-socket.io": "^10.4.12",
|
||||
"@nestjs/swagger": "^8.0.7",
|
||||
"@nestjs/websockets": "^10.4.12",
|
||||
"@prisma/client": "^6.0.1",
|
||||
"@prisma/client": "^6.1.0",
|
||||
"axios": "^1.7.7",
|
||||
"class-transformer": "^0.5.1",
|
||||
"class-validator": "^0.14.1",
|
||||
"joi": "^17.13.3",
|
||||
"jsonwebtoken": "^9.0.2",
|
||||
"jwks-rsa": "^3.1.0",
|
||||
"moment": "^2.30.1",
|
||||
"nestjs-prisma": "^0.23.0",
|
||||
"prisma": "^6.0.1",
|
||||
"prisma": "^6.1.0",
|
||||
"reflect-metadata": "^0.2.0",
|
||||
"rxjs": "^7.8.1",
|
||||
"socket.io": "^4.8.1"
|
||||
|
@ -8,15 +8,16 @@ datasource db {
|
||||
}
|
||||
|
||||
model User {
|
||||
id String @id
|
||||
username String
|
||||
role Role @default(STUDENT)
|
||||
createdAt DateTime @default(now())
|
||||
id String @id
|
||||
username String
|
||||
role Role @default(STUDENT)
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
Class Class[]
|
||||
SentMessages UserMessage[] @relation("SentMessages")
|
||||
ReceivedMessages UserMessage[] @relation("ReceivedMessages")
|
||||
RoomSurveyAnswerUser RoomSurveyAnswerUser[]
|
||||
RoomPresentator Room[] @relation("Presentator")
|
||||
}
|
||||
|
||||
model UserMessage {
|
||||
@ -42,32 +43,45 @@ model Class {
|
||||
}
|
||||
|
||||
model Room {
|
||||
id String @id @default(cuid())
|
||||
name String
|
||||
id String @id @default(cuid())
|
||||
name String
|
||||
date DateTime
|
||||
Presentator User @relation("Presentator", fields: [presentatorId], references: [id])
|
||||
presentatorId String
|
||||
|
||||
Class Class[]
|
||||
Messages RoomMessage[]
|
||||
Documents RoomDocument[]
|
||||
Surveys RoomSurvey[]
|
||||
Times RoomTime[]
|
||||
}
|
||||
|
||||
model RoomTime {
|
||||
id Int @id @default(autoincrement())
|
||||
startTime DateTime
|
||||
endTime DateTime
|
||||
Room Room @relation(fields: [roomId], references: [id], onDelete: Cascade)
|
||||
roomId String
|
||||
}
|
||||
|
||||
model RoomMessage {
|
||||
id Int @id @default(autoincrement())
|
||||
content String
|
||||
Room Room @relation(fields: [roomId], references: [id])
|
||||
Room Room @relation(fields: [roomId], references: [id], onDelete: Cascade)
|
||||
roomId String
|
||||
}
|
||||
|
||||
model RoomDocument {
|
||||
id Int @id @default(autoincrement())
|
||||
content String
|
||||
Room Room @relation(fields: [roomId], references: [id])
|
||||
Room Room @relation(fields: [roomId], references: [id], onDelete: Cascade)
|
||||
roomId String
|
||||
}
|
||||
|
||||
model RoomSurvey {
|
||||
id Int @id @default(autoincrement())
|
||||
content String
|
||||
Room Room @relation(fields: [roomId], references: [id])
|
||||
Room Room @relation(fields: [roomId], references: [id], onDelete: Cascade)
|
||||
roomId String
|
||||
createdAt DateTime @default(now())
|
||||
endAt DateTime?
|
||||
|
@ -2,12 +2,14 @@ import env from "@Config/env";
|
||||
import { Module } from "@nestjs/common";
|
||||
import { ConfigModule } from "@nestjs/config";
|
||||
import { envValidation } from "@Validations/env.validation";
|
||||
import { PrismaModule } from "nestjs-prisma";
|
||||
|
||||
import { AuthModule } from "@Modules/auth/auth.module";
|
||||
import { UserModule } from "@Modules/user/user.module";
|
||||
import { PrismaModule } from "nestjs-prisma";
|
||||
import { ClassModule } from "@Modules/class/class.module";
|
||||
import { MeModule } from '@Modules/me/me.module';
|
||||
|
||||
import { AppController } from "./app.controller";
|
||||
import { ClassModule } from "./modules/class/class.module";
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
@ -22,7 +24,8 @@ import { ClassModule } from "./modules/class/class.module";
|
||||
UserModule,
|
||||
AuthModule,
|
||||
ClassModule,
|
||||
MeModule,
|
||||
],
|
||||
controllers: [AppController]
|
||||
})
|
||||
export class AppModule {}
|
||||
export class AppModule { }
|
||||
|
@ -4,6 +4,7 @@ import {
|
||||
Controller,
|
||||
Delete,
|
||||
Get,
|
||||
HttpException,
|
||||
Param,
|
||||
Patch,
|
||||
Post,
|
||||
@ -31,6 +32,8 @@ import {
|
||||
ApiUnauthorizedResponse,
|
||||
} from "@nestjs/swagger";
|
||||
import { ClassEntity } from "./entities/class.entity";
|
||||
import { CreateRoomClassDto } from "./dto/create-room.dto";
|
||||
import { ClassRoomEntity } from "./entities/room.entity";
|
||||
|
||||
@Controller("class")
|
||||
@UseGuards(RolesGuard)
|
||||
@ -39,7 +42,7 @@ import { ClassEntity } from "./entities/class.entity";
|
||||
@Roles(["ADMIN"])
|
||||
@ApiUnauthorizedResponse(UnauthorizedResponse)
|
||||
export class ClassController {
|
||||
constructor(private readonly classService: ClassService) {}
|
||||
constructor(private readonly classService: ClassService) { }
|
||||
|
||||
@Post()
|
||||
@ApiOkResponse(ClassResponse)
|
||||
@ -55,48 +58,80 @@ export class ClassController {
|
||||
@ApiOperation({ summary: "Get all classes" })
|
||||
async findAll() {
|
||||
return await this.classService
|
||||
.findAll({})
|
||||
.findAll({ include: { ClassRoom: { include: { Times: true } } } })
|
||||
.then((classes) =>
|
||||
classes.map((class_) => new ClassEntity(class_)),
|
||||
);
|
||||
}
|
||||
|
||||
@Get(":id")
|
||||
@Get(":classId")
|
||||
@ApiOkResponse(ClassResponse)
|
||||
@ApiOperation({ summary: "Get a class by id" })
|
||||
async findOne(@Param("id") id: string) {
|
||||
async findOne(@Param("classId") classId: string) {
|
||||
return await this.classService
|
||||
.findOne(id)
|
||||
.findOne(classId)
|
||||
.then((class_) => new ClassEntity(class_));
|
||||
}
|
||||
|
||||
@Patch(":id")
|
||||
@Patch(":classId")
|
||||
@ApiOkResponse(ClassResponse)
|
||||
@ApiOperation({ summary: "Update a class by id" })
|
||||
async update(
|
||||
@Param("id") id: string,
|
||||
@Param("classId") classId: string,
|
||||
@Body() updateClassDto: UpdateClassDto,
|
||||
) {
|
||||
return await this.classService
|
||||
.update(id, updateClassDto)
|
||||
.update(classId, updateClassDto)
|
||||
.then((class_) => new ClassEntity(class_));
|
||||
}
|
||||
|
||||
@Delete(":id")
|
||||
@Delete(":classId")
|
||||
@ApiOkResponse(ClassResponse)
|
||||
@ApiOperation({ summary: "Remove a class by id" })
|
||||
async remove(@Param("id") id: string) {
|
||||
async remove(@Param("classId") classId: string) {
|
||||
return await this.classService
|
||||
.remove(id)
|
||||
.remove(classId)
|
||||
.then((class_) => new ClassEntity(class_));
|
||||
}
|
||||
|
||||
@Delete()
|
||||
@ApiOkResponse(ClassCountResponse)
|
||||
@ApiOperation({ summary: "Remove multiple classes by ids" })
|
||||
@ApiQuery({ name: "ids", required: true, type: [String] })
|
||||
async bulkRemove(@Query("ids") ids: string | string[]) {
|
||||
if (typeof ids === "string") ids = [ids];
|
||||
return await this.classService.bulkRemove(ids);
|
||||
@ApiQuery({ name: "classIds", required: true, type: [String] })
|
||||
async bulkRemove(@Query("classIds") classIds: string | string[]) {
|
||||
if (typeof classIds === "string") classIds = [classIds];
|
||||
return await this.classService.bulkRemove(classIds);
|
||||
}
|
||||
|
||||
@Get(":classId/students")
|
||||
@ApiOkResponse(ClassResponse)
|
||||
@ApiOperation({ summary: "Get all students in a class" })
|
||||
async getStudents(@Param("classId") classId: string) {
|
||||
return await this.classService
|
||||
.getStudents(classId)
|
||||
.then((class_) => new ClassEntity(class_));
|
||||
}
|
||||
|
||||
@Post(":classId/rooms")
|
||||
@ApiOkResponse(ClassResponse)
|
||||
@ApiOperation({ summary: "Add rooms to a class" })
|
||||
async addRooms(
|
||||
@Param("classId") classId: string,
|
||||
@Body() createRoomClassDto: CreateRoomClassDto,
|
||||
) {
|
||||
return await this.classService
|
||||
.createRoom(classId, createRoomClassDto)
|
||||
.then((room_) => new ClassRoomEntity(room_));
|
||||
}
|
||||
|
||||
@Get(":classId/rooms")
|
||||
@ApiOkResponse(ClassResponse)
|
||||
@ApiOperation({ summary: "Get rooms in a class" })
|
||||
async getRooms(@Param("classId") classId: string) {
|
||||
if (!classId) throw new HttpException("Class id is required", 400);
|
||||
|
||||
return await this.classService
|
||||
.getRooms(classId)
|
||||
.then((class_) => class_.map((room) => new ClassRoomEntity(room)));
|
||||
}
|
||||
}
|
||||
|
@ -1,12 +1,14 @@
|
||||
import { Injectable } from "@nestjs/common";
|
||||
import { HttpException, Injectable } from "@nestjs/common";
|
||||
import { CreateClassDto } from "./dto/create-class.dto";
|
||||
import { UpdateClassDto } from "./dto/update-class.dto";
|
||||
import { PrismaService } from "nestjs-prisma";
|
||||
import { Prisma } from "@prisma/client";
|
||||
import { CreateRoomClassDto } from "./dto/create-room.dto";
|
||||
import * as moment from "moment";
|
||||
|
||||
@Injectable()
|
||||
export class ClassService {
|
||||
constructor(private readonly prisma: PrismaService) {}
|
||||
constructor(private readonly prisma: PrismaService) { }
|
||||
|
||||
async create(createClassDto: CreateClassDto) {
|
||||
return await this.prisma.class.create({ data: createClassDto });
|
||||
@ -18,12 +20,14 @@ export class ClassService {
|
||||
cursor,
|
||||
where,
|
||||
orderBy,
|
||||
include
|
||||
}: {
|
||||
skip?: number;
|
||||
take?: number;
|
||||
cursor?: Prisma.ClassWhereUniqueInput;
|
||||
where?: Prisma.ClassWhereInput;
|
||||
orderBy?: Record<string, unknown>;
|
||||
include?: Prisma.ClassInclude;
|
||||
}) {
|
||||
return await this.prisma.class.findMany({
|
||||
skip,
|
||||
@ -31,6 +35,7 @@ export class ClassService {
|
||||
cursor,
|
||||
where,
|
||||
orderBy,
|
||||
include
|
||||
});
|
||||
}
|
||||
|
||||
@ -41,7 +46,9 @@ export class ClassService {
|
||||
async update(id: string, updateClassDto: UpdateClassDto) {
|
||||
return await this.prisma.class.update({
|
||||
where: { id },
|
||||
data: updateClassDto,
|
||||
data: {
|
||||
name: updateClassDto.name,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@ -54,4 +61,92 @@ export class ClassService {
|
||||
where: { id: { in: ids } },
|
||||
});
|
||||
}
|
||||
|
||||
async addStudents(classId: string, studentIds: string[]) {
|
||||
const Class = await this.prisma.class.findUnique({
|
||||
where: { id: classId },
|
||||
include: { Students: true },
|
||||
});
|
||||
|
||||
if (!Class)
|
||||
throw new HttpException("Class not found", 404);
|
||||
|
||||
const studentIdsToAdd = studentIds.filter(
|
||||
(studentId) =>
|
||||
!Class.Students.some((student) => student.id === studentId)
|
||||
);
|
||||
|
||||
if (studentIdsToAdd.length === 0) return Class;
|
||||
|
||||
return await this.prisma.class.update({
|
||||
where: { id: classId },
|
||||
data: {
|
||||
Students: {
|
||||
connect: studentIdsToAdd.map((studentId) => ({ id: studentId })),
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
async getStudents(classId: string) {
|
||||
return await this.prisma.class.findUnique({
|
||||
where: { id: classId },
|
||||
include: { Students: true },
|
||||
});
|
||||
}
|
||||
|
||||
async createRoom(classId: string, createRoomClassDto: CreateRoomClassDto) {
|
||||
// Check if end time is greater than start time
|
||||
const invalidTime = createRoomClassDto.times.find(
|
||||
(time) => moment(time.start, "HH:mm").isAfter(moment(time.end, "HH:mm"))
|
||||
);
|
||||
|
||||
if (invalidTime)
|
||||
throw new HttpException("Invalid time", 400);
|
||||
|
||||
// Check if date is in the past
|
||||
const invalidDate = moment(createRoomClassDto.date).isBefore(moment());
|
||||
|
||||
if (invalidDate)
|
||||
throw new HttpException("Invalid date", 400);
|
||||
|
||||
return await this.prisma.room.create({
|
||||
include: { Times: true },
|
||||
data: {
|
||||
name: createRoomClassDto.name,
|
||||
date: moment(createRoomClassDto.date).toDate(),
|
||||
presentatorId: createRoomClassDto.presentatorId,
|
||||
Class: {
|
||||
connect: { id: classId },
|
||||
},
|
||||
Times: {
|
||||
createMany: {
|
||||
data: createRoomClassDto.times.map((time) => ({
|
||||
startTime: moment(time.start, "HH:mm").toDate(),
|
||||
endTime: moment(time.end, "HH:mm").toDate(),
|
||||
})),
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
async getRooms(classId: string) {
|
||||
return await this.prisma.class.findUnique({
|
||||
where: { id: classId },
|
||||
include: { ClassRoom: { include: { Times: true, Presentator: true } } },
|
||||
}).then((class_) => class_.ClassRoom);
|
||||
}
|
||||
|
||||
async getUserClasses(userId: string) {
|
||||
return await this.prisma.class.findMany({
|
||||
where: {
|
||||
Students: {
|
||||
some: {
|
||||
id: userId,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
23
src/modules/class/dto/create-room.dto.ts
Normal file
23
src/modules/class/dto/create-room.dto.ts
Normal file
@ -0,0 +1,23 @@
|
||||
import { ApiProperty } from "@nestjs/swagger";
|
||||
import { IsArray, IsString, Matches } from "class-validator";
|
||||
|
||||
export class CreateRoomClassDto {
|
||||
@IsString()
|
||||
@ApiProperty()
|
||||
name: string;
|
||||
|
||||
@IsString()
|
||||
@ApiProperty()
|
||||
date: string;
|
||||
|
||||
@IsArray()
|
||||
@ApiProperty()
|
||||
times: {
|
||||
start: string;
|
||||
end: string;
|
||||
}[];
|
||||
|
||||
@IsString()
|
||||
@ApiProperty()
|
||||
presentatorId: string;
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
import { ApiProperty, ApiSchema } from "@nestjs/swagger";
|
||||
import { User } from "@prisma/client";
|
||||
import { Expose } from "class-transformer";
|
||||
|
||||
@ApiSchema({ name: "Class" })
|
||||
@ -15,6 +16,23 @@ export class ClassEntity {
|
||||
@ApiProperty()
|
||||
createdAt: Date;
|
||||
|
||||
@Expose()
|
||||
@ApiProperty()
|
||||
Students?: User[];
|
||||
|
||||
@Expose()
|
||||
@ApiProperty()
|
||||
ClassRoom?: {
|
||||
id: string;
|
||||
name: string;
|
||||
date: Date;
|
||||
|
||||
Times?: {
|
||||
startTime: Date;
|
||||
endTime: Date;
|
||||
}[];
|
||||
}[];
|
||||
|
||||
constructor(partial: Partial<ClassEntity>) {
|
||||
Object.assign(this, partial);
|
||||
}
|
||||
|
33
src/modules/class/entities/room.entity.ts
Normal file
33
src/modules/class/entities/room.entity.ts
Normal file
@ -0,0 +1,33 @@
|
||||
import { ApiProperty, ApiSchema } from "@nestjs/swagger";
|
||||
import { User } from "@prisma/client";
|
||||
import { Expose } from "class-transformer";
|
||||
|
||||
@ApiSchema({ name: "ClassRoom" })
|
||||
export class ClassRoomEntity {
|
||||
@Expose()
|
||||
@ApiProperty()
|
||||
id: string;
|
||||
|
||||
@Expose()
|
||||
@ApiProperty()
|
||||
name: string;
|
||||
|
||||
@Expose()
|
||||
@ApiProperty()
|
||||
date: Date;
|
||||
|
||||
@Expose()
|
||||
@ApiProperty()
|
||||
Times?: {
|
||||
startTime: Date;
|
||||
endTime: Date;
|
||||
}[];
|
||||
|
||||
@Expose()
|
||||
@ApiProperty()
|
||||
Presentator: User;
|
||||
|
||||
constructor(partial: Partial<ClassRoomEntity>) {
|
||||
Object.assign(this, partial);
|
||||
}
|
||||
}
|
26
src/modules/me/guards/isUserInClass.guard.ts
Normal file
26
src/modules/me/guards/isUserInClass.guard.ts
Normal file
@ -0,0 +1,26 @@
|
||||
import { ClassService } from '@/modules/class/class.service';
|
||||
import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common';
|
||||
|
||||
@Injectable()
|
||||
export class isUserInClassGuard implements CanActivate {
|
||||
constructor(private readonly classService: ClassService) { }
|
||||
|
||||
async canActivate(
|
||||
context: ExecutionContext,
|
||||
): Promise<boolean> {
|
||||
const request = context.switchToHttp().getRequest();
|
||||
const params = request.params;
|
||||
const classId = params.classId;
|
||||
const userId = request.user.id;
|
||||
|
||||
const userClasses = await this.classService.getUserClasses(userId);
|
||||
|
||||
if (!userClasses) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const userClass = userClasses.find((class_) => class_.id === classId);
|
||||
|
||||
return !!userClass;
|
||||
}
|
||||
}
|
30
src/modules/me/me.controller.ts
Normal file
30
src/modules/me/me.controller.ts
Normal file
@ -0,0 +1,30 @@
|
||||
import { UnauthorizedResponse } from '@/ApiResponses/UnauthorizedResponse';
|
||||
import { Controller, Get, Param, Req, UseGuards } from '@nestjs/common';
|
||||
import { ApiBearerAuth, ApiOkResponse, ApiUnauthorizedResponse } from '@nestjs/swagger';
|
||||
import { Request } from 'express';
|
||||
import { JwtAuthGuard } from '../auth/guards/jwt.guard';
|
||||
import { RolesGuard } from '../auth/guards/role.guard';
|
||||
import { isUserInClassGuard } from './guards/isUserInClass.guard';
|
||||
import { MeService } from './me.service';
|
||||
|
||||
@Controller('@me')
|
||||
@UseGuards(RolesGuard)
|
||||
@UseGuards(JwtAuthGuard)
|
||||
@ApiBearerAuth()
|
||||
@ApiUnauthorizedResponse(UnauthorizedResponse)
|
||||
export class MeController {
|
||||
constructor(private readonly meService: MeService) { }
|
||||
|
||||
@Get("/class")
|
||||
@ApiOkResponse({ description: 'Get all classes' })
|
||||
async getMyClasses(@Req() req: Request) {
|
||||
return await this.meService.getMyClasses(req.user.id);
|
||||
}
|
||||
|
||||
@Get("/class/:classId/rooms")
|
||||
@UseGuards(isUserInClassGuard)
|
||||
@ApiOkResponse({ description: 'Get all rooms for a class' })
|
||||
async getMyRooms(@Param('classId') classId: string) {
|
||||
return await this.meService.getMyRooms(classId);
|
||||
}
|
||||
}
|
13
src/modules/me/me.module.ts
Normal file
13
src/modules/me/me.module.ts
Normal file
@ -0,0 +1,13 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { MeController } from './me.controller';
|
||||
import { ClassModule } from '../class/class.module';
|
||||
import { ClassService } from '../class/class.service';
|
||||
import { UserModule } from '../user/user.module';
|
||||
import { MeService } from './me.service';
|
||||
|
||||
@Module({
|
||||
controllers: [MeController],
|
||||
imports: [ClassModule, UserModule],
|
||||
providers: [ClassService, MeService],
|
||||
})
|
||||
export class MeModule { }
|
15
src/modules/me/me.service.ts
Normal file
15
src/modules/me/me.service.ts
Normal file
@ -0,0 +1,15 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { ClassService } from '../class/class.service';
|
||||
|
||||
@Injectable()
|
||||
export class MeService {
|
||||
constructor(private readonly classService: ClassService) { }
|
||||
|
||||
async getMyClasses(userId: string) {
|
||||
return await this.classService.getUserClasses(userId);
|
||||
}
|
||||
|
||||
async getMyRooms(classId: string) {
|
||||
return await this.classService.getRooms(classId)
|
||||
}
|
||||
}
|
@ -10,6 +10,7 @@ import {
|
||||
Param,
|
||||
Patch,
|
||||
Query,
|
||||
Req,
|
||||
UseGuards
|
||||
} from "@nestjs/common";
|
||||
import {
|
||||
@ -28,6 +29,7 @@ import {
|
||||
import { UpdateUserDTO } from "./dto/update-user.dto";
|
||||
import { UserEntity } from "./entities/user.entity";
|
||||
import { UserService } from "./user.service";
|
||||
import { Request } from "express";
|
||||
|
||||
@Controller("user")
|
||||
@UseGuards(RolesGuard)
|
||||
@ -50,7 +52,9 @@ export class UserController {
|
||||
@Get(":id")
|
||||
@ApiOkResponse(UserResponse)
|
||||
@ApiOperation({ summary: "Get user by id" })
|
||||
async findOne(@Param("id") id: string): Promise<UserEntity> {
|
||||
async findOne(@Param("id") id: string, @Req() req: Request): Promise<UserEntity> {
|
||||
if (id === "@me") id = req.user.id;
|
||||
|
||||
return this.userService
|
||||
.findOne(id)
|
||||
.then((user) => new UserEntity(user));
|
||||
|
@ -7,7 +7,7 @@ import { UpdateUserDTO } from "./dto/update-user.dto";
|
||||
|
||||
@Injectable()
|
||||
export class UserService {
|
||||
constructor(private readonly prisma: PrismaService) {}
|
||||
constructor(private readonly prisma: PrismaService) { }
|
||||
|
||||
async findAll({
|
||||
skip,
|
||||
@ -41,7 +41,6 @@ export class UserService {
|
||||
let user = await this.prisma.user.findFirst({
|
||||
where: {
|
||||
id,
|
||||
username,
|
||||
},
|
||||
});
|
||||
|
||||
@ -55,6 +54,13 @@ export class UserService {
|
||||
role: isFirstUser ? "ADMIN" : "STUDENT",
|
||||
},
|
||||
});
|
||||
} else if (user.username !== username) {
|
||||
user = await this.prisma.user.update({
|
||||
where: { id },
|
||||
data: {
|
||||
username,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
return user;
|
||||
@ -74,6 +80,7 @@ export class UserService {
|
||||
where: { id },
|
||||
data: {
|
||||
username: updateUserInput.username,
|
||||
role: updateUserInput.role,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
@ -5,7 +5,7 @@
|
||||
"removeComments": true,
|
||||
"emitDecoratorMetadata": true,
|
||||
"experimentalDecorators": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"allowSyntheticDefaultImports": false,
|
||||
"target": "ES2021",
|
||||
"sourceMap": true,
|
||||
"outDir": "./dist",
|
||||
|
99
yarn.lock
99
yarn.lock
@ -414,46 +414,46 @@
|
||||
resolved "https://registry.yarnpkg.com/@pkgr/core/-/core-0.1.1.tgz#1ec17e2edbec25c8306d424ecfbf13c7de1aaa31"
|
||||
integrity sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==
|
||||
|
||||
"@prisma/client@^6.0.1":
|
||||
version "6.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@prisma/client/-/client-6.0.1.tgz#e24c5a44fb46d04a92426879bd9f8a2c28338420"
|
||||
integrity sha512-60w7kL6bUxz7M6Gs/V+OWMhwy94FshpngVmOY05TmGD0Lhk+Ac0ZgtjlL6Wll9TD4G03t4Sq1wZekNVy+Xdlbg==
|
||||
"@prisma/client@^6.1.0":
|
||||
version "6.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@prisma/client/-/client-6.1.0.tgz#179d3b70586e7be522f6f1f0a82cca01396f719a"
|
||||
integrity sha512-AbQYc5+EJKm1Ydfq3KxwcGiy7wIbm4/QbjCKWWoNROtvy7d6a3gmAGkKjK0iUCzh+rHV8xDhD5Cge8ke/kiy5Q==
|
||||
|
||||
"@prisma/debug@6.0.1":
|
||||
version "6.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@prisma/debug/-/debug-6.0.1.tgz#8407544dd89c8bf85a6e9889ea263fe0e1ccebe2"
|
||||
integrity sha512-jQylgSOf7ibTVxqBacnAlVGvek6fQxJIYCQOeX2KexsfypNzXjJQSS2o5s+Mjj2Np93iSOQUaw6TvPj8syhG4w==
|
||||
"@prisma/debug@6.1.0":
|
||||
version "6.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@prisma/debug/-/debug-6.1.0.tgz#a27a1d144f72a3bc95061ecb0255e7554d9d59ec"
|
||||
integrity sha512-0himsvcM4DGBTtvXkd2Tggv6sl2JyUYLzEGXXleFY+7Kp6rZeSS3hiTW9mwtUlXrwYbJP6pwlVNB7jYElrjWUg==
|
||||
|
||||
"@prisma/engines-version@5.23.0-27.5dbef10bdbfb579e07d35cc85fb1518d357cb99e":
|
||||
version "5.23.0-27.5dbef10bdbfb579e07d35cc85fb1518d357cb99e"
|
||||
resolved "https://registry.yarnpkg.com/@prisma/engines-version/-/engines-version-5.23.0-27.5dbef10bdbfb579e07d35cc85fb1518d357cb99e.tgz#2db5a05d014aac504e8574da6b96ac3d9a617526"
|
||||
integrity sha512-JmIds0Q2/vsOmnuTJYxY4LE+sajqjYKhLtdOT6y4imojqv5d/aeVEfbBGC74t8Be1uSp0OP8lxIj2OqoKbLsfQ==
|
||||
"@prisma/engines-version@6.1.0-21.11f085a2012c0f4778414c8db2651556ee0ef959":
|
||||
version "6.1.0-21.11f085a2012c0f4778414c8db2651556ee0ef959"
|
||||
resolved "https://registry.yarnpkg.com/@prisma/engines-version/-/engines-version-6.1.0-21.11f085a2012c0f4778414c8db2651556ee0ef959.tgz#0b21ebf57362ffe35d0760c39855f90bbfa0f2fd"
|
||||
integrity sha512-PdJqmYM2Fd8K0weOOtQThWylwjsDlTig+8Pcg47/jszMuLL9iLIaygC3cjWJLda69siRW4STlCTMSgOjZzvKPQ==
|
||||
|
||||
"@prisma/engines@6.0.1":
|
||||
version "6.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@prisma/engines/-/engines-6.0.1.tgz#b64afa9b4e2bedc2b6488b15f9d867c8672b33ee"
|
||||
integrity sha512-4hxzI+YQIR2uuDyVsDooFZGu5AtixbvM2psp+iayDZ4hRrAHo/YwgA17N23UWq7G6gRu18NvuNMb48qjP3DPQw==
|
||||
"@prisma/engines@6.1.0":
|
||||
version "6.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@prisma/engines/-/engines-6.1.0.tgz#2195244a8ce33839a8131e4465624e21d1f8d042"
|
||||
integrity sha512-GnYJbCiep3Vyr1P/415ReYrgJUjP79fBNc1wCo7NP6Eia0CzL2Ot9vK7Infczv3oK7JLrCcawOSAxFxNFsAERQ==
|
||||
dependencies:
|
||||
"@prisma/debug" "6.0.1"
|
||||
"@prisma/engines-version" "5.23.0-27.5dbef10bdbfb579e07d35cc85fb1518d357cb99e"
|
||||
"@prisma/fetch-engine" "6.0.1"
|
||||
"@prisma/get-platform" "6.0.1"
|
||||
"@prisma/debug" "6.1.0"
|
||||
"@prisma/engines-version" "6.1.0-21.11f085a2012c0f4778414c8db2651556ee0ef959"
|
||||
"@prisma/fetch-engine" "6.1.0"
|
||||
"@prisma/get-platform" "6.1.0"
|
||||
|
||||
"@prisma/fetch-engine@6.0.1":
|
||||
version "6.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@prisma/fetch-engine/-/fetch-engine-6.0.1.tgz#1e3affb7a749caaf366239c7d61ae7b19d3e7e00"
|
||||
integrity sha512-T36bWFVGeGYYSyYOj9d+O9G3sBC+pAyMC+jc45iSL63/Haq1GrYjQPgPMxrEj9m739taXrupoysRedQ+VyvM/Q==
|
||||
"@prisma/fetch-engine@6.1.0":
|
||||
version "6.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@prisma/fetch-engine/-/fetch-engine-6.1.0.tgz#2a5174787bf57c9b1d5d400bb923e0dc6a73a794"
|
||||
integrity sha512-asdFi7TvPlEZ8CzSZ/+Du5wZ27q6OJbRSXh+S8ISZguu+S9KtS/gP7NeXceZyb1Jv1SM1S5YfiCv+STDsG6rrg==
|
||||
dependencies:
|
||||
"@prisma/debug" "6.0.1"
|
||||
"@prisma/engines-version" "5.23.0-27.5dbef10bdbfb579e07d35cc85fb1518d357cb99e"
|
||||
"@prisma/get-platform" "6.0.1"
|
||||
"@prisma/debug" "6.1.0"
|
||||
"@prisma/engines-version" "6.1.0-21.11f085a2012c0f4778414c8db2651556ee0ef959"
|
||||
"@prisma/get-platform" "6.1.0"
|
||||
|
||||
"@prisma/get-platform@6.0.1":
|
||||
version "6.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@prisma/get-platform/-/get-platform-6.0.1.tgz#322dae7e8862c9b849384b820b81ecd4006e1d63"
|
||||
integrity sha512-zspC9vlxAqx4E6epMPMLLBMED2VD8axDe8sPnquZ8GOsn6tiacWK0oxrGK4UAHYzYUVuMVUApJbdXB2dFpLhvg==
|
||||
"@prisma/get-platform@6.1.0":
|
||||
version "6.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@prisma/get-platform/-/get-platform-6.1.0.tgz#d4394a24ef91af6675a92382ed40e6e6e07eeb13"
|
||||
integrity sha512-ia8bNjboBoHkmKGGaWtqtlgQOhCi7+f85aOkPJKgNwWvYrT6l78KgojLekE8zMhVk0R9lWcifV0Pf8l3/15V0Q==
|
||||
dependencies:
|
||||
"@prisma/debug" "6.0.1"
|
||||
"@prisma/debug" "6.1.0"
|
||||
|
||||
"@scarf/scarf@=1.4.0":
|
||||
version "1.4.0"
|
||||
@ -2563,6 +2563,11 @@ mkdirp@^0.5.4:
|
||||
dependencies:
|
||||
minimist "^1.2.6"
|
||||
|
||||
moment@^2.30.1:
|
||||
version "2.30.1"
|
||||
resolved "https://registry.yarnpkg.com/moment/-/moment-2.30.1.tgz#f8c91c07b7a786e30c59926df530b4eac96974ae"
|
||||
integrity sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==
|
||||
|
||||
ms@2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
|
||||
@ -2821,12 +2826,12 @@ prettier@^3.0.0:
|
||||
resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.4.2.tgz#a5ce1fb522a588bf2b78ca44c6e6fe5aa5a2b13f"
|
||||
integrity sha512-e9MewbtFo+Fevyuxn/4rrcDAaq0IYxPGLvObpQjiZBMAzB9IGmzlnG9RZy3FFas+eBMu2vA0CszMeduow5dIuQ==
|
||||
|
||||
prisma@^6.0.1:
|
||||
version "6.0.1"
|
||||
resolved "https://registry.yarnpkg.com/prisma/-/prisma-6.0.1.tgz#63bf769c798b98986aeaf9cddbf12193f9e2c356"
|
||||
integrity sha512-CaMNFHkf+DDq8zq3X/JJsQ4Koy7dyWwwtOKibkT/Am9j/tDxcfbg7+lB1Dzhx18G/+RQCMgjPYB61bhRqteNBQ==
|
||||
prisma@^6.1.0:
|
||||
version "6.1.0"
|
||||
resolved "https://registry.yarnpkg.com/prisma/-/prisma-6.1.0.tgz#738f657fdd5ab8e6775f385db81bf7e61c70fbaf"
|
||||
integrity sha512-aFI3Yi+ApUxkwCJJwyQSwpyzUX7YX3ihzuHNHOyv4GJg3X5tQsmRaJEnZ+ZyfHpMtnyahhmXVfbTZ+lS8ZtfKw==
|
||||
dependencies:
|
||||
"@prisma/engines" "6.0.1"
|
||||
"@prisma/engines" "6.1.0"
|
||||
optionalDependencies:
|
||||
fsevents "2.3.3"
|
||||
|
||||
@ -3161,7 +3166,16 @@ streamsearch@^1.1.0:
|
||||
resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-1.1.0.tgz#404dd1e2247ca94af554e841a8ef0eaa238da764"
|
||||
integrity sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==
|
||||
|
||||
"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
|
||||
"string-width-cjs@npm:string-width@^4.2.0":
|
||||
version "4.2.3"
|
||||
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
|
||||
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
|
||||
dependencies:
|
||||
emoji-regex "^8.0.0"
|
||||
is-fullwidth-code-point "^3.0.0"
|
||||
strip-ansi "^6.0.1"
|
||||
|
||||
string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
|
||||
version "4.2.3"
|
||||
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
|
||||
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
|
||||
@ -3193,7 +3207,14 @@ string_decoder@~1.1.1:
|
||||
dependencies:
|
||||
safe-buffer "~5.1.0"
|
||||
|
||||
"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1:
|
||||
"strip-ansi-cjs@npm:strip-ansi@^6.0.1":
|
||||
version "6.0.1"
|
||||
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
|
||||
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
|
||||
dependencies:
|
||||
ansi-regex "^5.0.1"
|
||||
|
||||
strip-ansi@^6.0.0, strip-ansi@^6.0.1:
|
||||
version "6.0.1"
|
||||
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
|
||||
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
|
||||
|
Loading…
Reference in New Issue
Block a user