diff --git a/src/controller/session.controller.ts b/src/controller/session.controller.ts index 7517729..406aa8e 100644 --- a/src/controller/session.controller.ts +++ b/src/controller/session.controller.ts @@ -1,4 +1,5 @@ -import { Body, Controller, Get, Post, Query, Req } from '@nestjs/common'; +import { Body, Controller, Get, Post, Req } from '@nestjs/common'; +import { SessionStatus } from 'src/dto/session-status'; import { SessionService } from 'src/service/session.service'; import { UserService } from 'src/service/user.service'; @@ -10,11 +11,36 @@ export class SessionController { ) {} @Post('/create') - public createSession() { - this.sessionService.createSession( - new Date(Date.now() + 24 * 3600 * 1000), - 10, - ); + public createSession( + @Req() request, + @Body('date') date: number, + @Body('size') size: number, + @Body('status') status?: SessionStatus, + ) { + const userId = request.userId; + this.userService.verifyAdminRole(userId); + this.sessionService.createSession(new Date(date), size, status); + } + + @Post('/open') + public openSession(@Req() request, @Body('sessionId') sessionId: string) { + const userId = request.userId; + this.userService.verifyAdminRole(userId); + this.sessionService.openSession(sessionId); + } + + @Post('/close') + public closeSession(@Req() request, @Body('sessionId') sessionId: string) { + const userId = request.userId; + this.userService.verifyAdminRole(userId); + this.sessionService.closeSession(sessionId); + } + + @Post('/cancel') + public cancelSession(@Req() request, @Body('sessionId') sessionId: string) { + const userId = request.userId; + this.userService.verifyAdminRole(userId); + this.sessionService.cancelSession(sessionId); } @Get() diff --git a/src/dto/user-role.ts b/src/dto/user-role.ts new file mode 100644 index 0000000..54b75e2 --- /dev/null +++ b/src/dto/user-role.ts @@ -0,0 +1,4 @@ +export enum UserRole { + CUSTOMER, + ADMIN, +} diff --git a/src/dto/user.ts b/src/dto/user.ts index 085f270..cbe9b01 100644 --- a/src/dto/user.ts +++ b/src/dto/user.ts @@ -10,6 +10,7 @@ import { import { Purchase } from './purchase'; import { Session } from './session'; import { Token } from './token'; +import { UserRole } from './user-role'; @Entity('USERS') export class User { @@ -29,6 +30,9 @@ export class User { @JoinTable() joinedSessions: Session[]; - @OneToOne(() => Token, (token) => token.user, { cascade: true }) + @OneToOne(() => Token, (token) => token.user, { cascade: ['insert'] }) token: Token; + + @Column() + role: UserRole; } diff --git a/src/service/session.service.ts b/src/service/session.service.ts index db1714d..08ad953 100644 --- a/src/service/session.service.ts +++ b/src/service/session.service.ts @@ -2,7 +2,7 @@ import { Injectable, Logger, NotFoundException } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; import { Session } from 'src/dto/session'; import { User } from 'src/dto/user'; -import { Repository } from 'typeorm'; +import { In, Repository } from 'typeorm'; import { TokenService } from './token.service'; import { SessionStatus } from 'src/dto/session-status'; @@ -15,19 +15,47 @@ export class SessionService { private tokenService: TokenService, ) {} - public createSession(date: Date, size: number) { + public createSession(date: Date, size: number, status?: SessionStatus) { const session = this.sessionRepo.create({ users: [], date, size, - status: SessionStatus.OPEN, + status: status || SessionStatus.OPEN, }); this.sessionRepo.save(session); } + public async openSession(sessionId: string) { + const session = await this.sessionRepo.findOneOrFail({ + where: { id: sessionId, status: SessionStatus.SCHEDULED }, + }); + session.status = SessionStatus.OPEN; + await this.sessionRepo.save(session); + } + + public async cancelSession(sessionId: string) { + const session = await this.sessionRepo.findOneOrFail({ + where: { + id: sessionId, + status: In([SessionStatus.SCHEDULED, SessionStatus.OPEN]), + }, + }); + Promise.all( + session.users.map( + async (user) => await this.tokenService.unlockToken(user), + ), + ); + session.users = []; + session.status = SessionStatus.CANCELLED; + await this.sessionRepo.save(session); + } + public async closeSession(sessionId: string) { const session = await this.sessionRepo.findOneOrFail({ - where: { id: sessionId }, + where: { + id: sessionId, + status: In([SessionStatus.SCHEDULED, SessionStatus.OPEN]), + }, }); Promise.all( session.users.map( @@ -50,6 +78,7 @@ export class SessionService { const session = await this.sessionRepo.findOneOrFail({ where: { id: sessionId, + status: SessionStatus.OPEN, }, relations: { users: true, @@ -74,6 +103,7 @@ export class SessionService { const session = await this.sessionRepo.findOneOrFail({ where: { id: sessionId, + status: SessionStatus.OPEN, }, relations: { users: true, diff --git a/src/service/user.service.ts b/src/service/user.service.ts index 3ceea84..a1d6790 100644 --- a/src/service/user.service.ts +++ b/src/service/user.service.ts @@ -3,6 +3,7 @@ import { InjectRepository } from '@nestjs/typeorm'; import { User } from 'src/dto/user'; import { Repository } from 'typeorm'; import * as bcrypt from 'bcrypt'; +import { UserRole } from 'src/dto/user-role'; @Injectable() export class UserService { @@ -44,6 +45,7 @@ export class UserService { password: await bcrypt.hash(password, 10), purchases: [], joinedSessions: [], + role: UserRole.CUSTOMER, token: { purchasedTokens: 0, lockedTokens: 0, @@ -52,4 +54,10 @@ export class UserService { }); return this.userRepo.save(user); } + + public async verifyAdminRole(userId: string) { + await this.userRepo.findOneOrFail({ + where: { id: userId, role: UserRole.ADMIN }, + }); + } }