From 53768b244612ea30b722174320c231a60b5607cc Mon Sep 17 00:00:00 2001 From: yang Date: Mon, 18 Nov 2024 19:56:36 +0900 Subject: [PATCH 1/4] =?UTF-8?q?feat:=20Event=20Enum=EC=9D=84=20=EC=9E=91?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/server/src/task/domain/eventType.enum.ts | 7 +++++++ .../src/task/domain/information.type.ts | 7 +++++++ apps/server/src/task/dto/task-event.dto.ts | 19 +++++++++++++++++++ apps/server/src/task/service/task.service.ts | 9 ++++++--- 4 files changed, 39 insertions(+), 3 deletions(-) create mode 100644 apps/server/src/task/domain/eventType.enum.ts create mode 100644 apps/server/src/task/domain/information.type.ts create mode 100644 apps/server/src/task/dto/task-event.dto.ts diff --git a/apps/server/src/task/domain/eventType.enum.ts b/apps/server/src/task/domain/eventType.enum.ts new file mode 100644 index 0000000..f48f71a --- /dev/null +++ b/apps/server/src/task/domain/eventType.enum.ts @@ -0,0 +1,7 @@ +export enum EventType { + 'CREATE_TASK' = 'CREATE_TASK', + 'DELETE_TASK' = 'DELETE_TASK', + 'INSERT_TITLE' = 'INSERT_TITLE', + 'DELETE_TITLE' = 'DELETE_TITLE', + 'UPDATE_POSITION' = 'UPDATE_POSITION', +} diff --git a/apps/server/src/task/domain/information.type.ts b/apps/server/src/task/domain/information.type.ts new file mode 100644 index 0000000..6a2deca --- /dev/null +++ b/apps/server/src/task/domain/information.type.ts @@ -0,0 +1,7 @@ +type Information = { + position: number; + + content: string; + + length: number; +}; diff --git a/apps/server/src/task/dto/task-event.dto.ts b/apps/server/src/task/dto/task-event.dto.ts new file mode 100644 index 0000000..647902a --- /dev/null +++ b/apps/server/src/task/dto/task-event.dto.ts @@ -0,0 +1,19 @@ +import { IsNumber, IsNotEmpty, IsString, IsEnum } from 'class-validator'; +import { EventType } from '../domain/eventType.enum'; + +export class TaskEvent { + @IsNumber() + taskId: number; + + @IsNumber() + sectionId: number; + + @IsString() + position: string; + + @IsNotEmpty() + @IsEnum(EventType) + event: EventType; + + title: Information; +} diff --git a/apps/server/src/task/service/task.service.ts b/apps/server/src/task/service/task.service.ts index 51b734c..ddea313 100644 --- a/apps/server/src/task/service/task.service.ts +++ b/apps/server/src/task/service/task.service.ts @@ -13,12 +13,13 @@ import { DeleteTaskResponse } from '@/task/dto/delete-task-response.dto'; import { CreateTaskResponse } from '@/task/dto/create-task-response.dto'; import { Project } from '@/project/entity/project.entity'; import { CreateTaskRequest } from '@/task/dto/create-task-request.dto'; -import { Snapshot } from '@/task/domain/snapshot'; import { CustomResponse } from '@/task/domain/custom-response.interface'; +import { Snapshot } from '../domain/snapshot'; @Injectable() export class TaskService { private snapshots: Map = new Map(); + private operations: Map = new Map(); private connections: Map = new Map(); @@ -62,8 +63,8 @@ export class TaskService { status: 200, message: '스냅샷에 변경 사항이 발생했습니다.', result: { - version: snapshot.version, - project: snapshot.project, + ersion: snapshot.version, + roject: snapshot.project, }, }); } @@ -130,6 +131,8 @@ export class TaskService { return taskBySection; } + updateQueue() {} + async update(id: number, userId: number, updateTaskRequest: UpdateTaskRequest) { const prevTask = await this.findTaskOrThrow(id); const prevSectionId = prevTask.section.id; From 1f2045c7b4a74b49efda4a8604fc552df9ab2b2d Mon Sep 17 00:00:00 2001 From: yang Date: Mon, 18 Nov 2024 20:33:20 +0900 Subject: [PATCH 2/4] =?UTF-8?q?feat:=20=EB=B3=80=EA=B2=BD=20=EC=82=AC?= =?UTF-8?q?=ED=95=AD=20=EC=88=98=EC=8B=A0=20=EC=97=94=EB=93=9C=ED=8F=AC?= =?UTF-8?q?=EC=9D=B8=ED=8A=B8=EB=A5=BC=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/server/package.json | 3 +- .../project/controller/project.controller.ts | 43 ++++++++++++++++++- apps/server/src/project/project.module.ts | 3 +- apps/server/src/task/domain/eventType.enum.ts | 14 +++--- .../src/task/domain/information.type.ts | 14 +++--- apps/server/src/task/dto/task-event.dto.ts | 38 ++++++++-------- apps/server/src/task/service/task.service.ts | 8 ++-- apps/server/src/task/task.module.ts | 1 + 8 files changed, 83 insertions(+), 41 deletions(-) diff --git a/apps/server/package.json b/apps/server/package.json index 7641489..51ef898 100644 --- a/apps/server/package.json +++ b/apps/server/package.json @@ -23,6 +23,7 @@ "@nestjs/common": "^10.0.0", "@nestjs/config": "^3.3.0", "@nestjs/core": "^10.0.0", + "@nestjs/event-emitter": "^2.1.1", "@nestjs/jwt": "^10.2.0", "@nestjs/passport": "^10.0.3", "@nestjs/platform-express": "^10.0.0", @@ -43,8 +44,8 @@ "@nestjs/cli": "^10.0.0", "@nestjs/schematics": "^10.0.0", "@nestjs/testing": "^10.0.0", - "@types/express": "^4.17.17", "@types/bcrypt": "^5.0.2", + "@types/express": "^4.17.17", "@types/jest": "^29.5.2", "@types/node": "^20.3.1", "@types/passport-jwt": "^4.0.1", diff --git a/apps/server/src/project/controller/project.controller.ts b/apps/server/src/project/controller/project.controller.ts index f0b9f8f..62cb432 100644 --- a/apps/server/src/project/controller/project.controller.ts +++ b/apps/server/src/project/controller/project.controller.ts @@ -1,4 +1,13 @@ -import { Body, Controller, Get, Param, Patch, Post, UseGuards } from '@nestjs/common'; +import { + BadRequestException, + Body, + Controller, + Get, + Param, + Patch, + Post, + UseGuards, +} from '@nestjs/common'; import { ProjectService } from '@/project/service/project.service'; import { AccessTokenGuard } from '@/account/guard/accessToken.guard'; import { CreateProjectRequest } from '@/project/dto/create-project-request.dto'; @@ -6,11 +15,17 @@ import { AuthUser } from '@/account/decorator/authUser.decorator'; import { Account } from '@/account/entity/account.entity'; import { InviteUserRequest } from '@/project/dto/invite-user-request.dto'; import { UpdateContributorRequest } from '@/project/dto/update-contributor-request.dts'; +import { TaskEvent } from '@/task/dto/task-event.dto'; +import { TaskService } from '@/task/service/task.service'; +import { EventType } from '@/task/domain/eventType.enum'; @UseGuards(AccessTokenGuard) @Controller('project') export class ProjectController { - constructor(private projectService: ProjectService) {} + constructor( + private projectService: ProjectService, + private taskService: TaskService + ) {} @Get(':id/members') getMembers(@AuthUser() user: Account, @Param('id') projectId: number) { @@ -38,4 +53,28 @@ export class ProjectController { await this.projectService.updateInvitation(user.id, body.contributorId, body.status); return { message: 'Successfully update invitation', success: true }; } + + @Post(':id/update') + async handleEvent(@AuthUser() user: Account, @Body() taskEvent: TaskEvent) { + const event = taskEvent.event; + let response; + switch (event) { + case EventType.CREATE_TASK: + response = await this.taskService.create(user.id, taskEvent); + break; + case EventType.DELETE_TASK: + response = await this.taskService.delete(user.id, taskEvent); + break; + case EventType.UPDATE_POSITION: + response = await this.taskService.move(user.id, taskEvent); + break; + case EventType.INSERT_TITLE: + case EventType.DELETE_TITLE: + response = await this.taskService.update(user.id, taskEvent); + break; + default: + throw new BadRequestException('올바르지 않은 이벤트 타입입니다.'); + } + return response; + } } diff --git a/apps/server/src/project/project.module.ts b/apps/server/src/project/project.module.ts index d0b5292..80f968f 100644 --- a/apps/server/src/project/project.module.ts +++ b/apps/server/src/project/project.module.ts @@ -8,9 +8,10 @@ import { Account } from '@/account/entity/account.entity'; import { Task } from '@/task/domain/task.entity'; import { ProjectsController } from '@/project/controller/projects.controller'; import { Section } from '@/task/domain/section.entity'; +import { TaskService } from '@/task/service/task.service'; @Module({ - imports: [TypeOrmModule.forFeature([Project, Contributor, Account, Task, Section])], + imports: [TypeOrmModule.forFeature([Project, Contributor, Account, Task, Section]), TaskService], controllers: [ProjectController, ProjectsController], providers: [ProjectService], }) diff --git a/apps/server/src/task/domain/eventType.enum.ts b/apps/server/src/task/domain/eventType.enum.ts index f48f71a..79882cd 100644 --- a/apps/server/src/task/domain/eventType.enum.ts +++ b/apps/server/src/task/domain/eventType.enum.ts @@ -1,7 +1,7 @@ -export enum EventType { - 'CREATE_TASK' = 'CREATE_TASK', - 'DELETE_TASK' = 'DELETE_TASK', - 'INSERT_TITLE' = 'INSERT_TITLE', - 'DELETE_TITLE' = 'DELETE_TITLE', - 'UPDATE_POSITION' = 'UPDATE_POSITION', -} +export enum EventType { + 'CREATE_TASK' = 'CREATE_TASK', + 'DELETE_TASK' = 'DELETE_TASK', + 'INSERT_TITLE' = 'INSERT_TITLE', + 'DELETE_TITLE' = 'DELETE_TITLE', + 'UPDATE_POSITION' = 'UPDATE_POSITION', +} diff --git a/apps/server/src/task/domain/information.type.ts b/apps/server/src/task/domain/information.type.ts index 6a2deca..63a784a 100644 --- a/apps/server/src/task/domain/information.type.ts +++ b/apps/server/src/task/domain/information.type.ts @@ -1,7 +1,7 @@ -type Information = { - position: number; - - content: string; - - length: number; -}; +type Information = { + position: number; + + content: string; + + length: number; +}; diff --git a/apps/server/src/task/dto/task-event.dto.ts b/apps/server/src/task/dto/task-event.dto.ts index 647902a..4c9c0b1 100644 --- a/apps/server/src/task/dto/task-event.dto.ts +++ b/apps/server/src/task/dto/task-event.dto.ts @@ -1,19 +1,19 @@ -import { IsNumber, IsNotEmpty, IsString, IsEnum } from 'class-validator'; -import { EventType } from '../domain/eventType.enum'; - -export class TaskEvent { - @IsNumber() - taskId: number; - - @IsNumber() - sectionId: number; - - @IsString() - position: string; - - @IsNotEmpty() - @IsEnum(EventType) - event: EventType; - - title: Information; -} +import { IsNumber, IsNotEmpty, IsString, IsEnum } from 'class-validator'; +import { EventType } from '../domain/eventType.enum'; + +export class TaskEvent { + @IsNumber() + taskId: number; + + @IsNumber() + sectionId: number; + + @IsString() + position: string; + + @IsNotEmpty() + @IsEnum(EventType) + event: EventType; + + title: Information; +} diff --git a/apps/server/src/task/service/task.service.ts b/apps/server/src/task/service/task.service.ts index ddea313..081eed9 100644 --- a/apps/server/src/task/service/task.service.ts +++ b/apps/server/src/task/service/task.service.ts @@ -15,11 +15,13 @@ import { Project } from '@/project/entity/project.entity'; import { CreateTaskRequest } from '@/task/dto/create-task-request.dto'; import { CustomResponse } from '@/task/domain/custom-response.interface'; import { Snapshot } from '../domain/snapshot'; +import { EventEmitter2 } from '@nestjs/event-emitter'; @Injectable() export class TaskService { private snapshots: Map = new Map(); private operations: Map = new Map(); + private eventEmitter: EventEmitter2 = new EventEmitter2(); private connections: Map = new Map(); @@ -63,8 +65,8 @@ export class TaskService { status: 200, message: '스냅샷에 변경 사항이 발생했습니다.', result: { - ersion: snapshot.version, - roject: snapshot.project, + version: snapshot.version, + project: snapshot.project, }, }); } @@ -131,8 +133,6 @@ export class TaskService { return taskBySection; } - updateQueue() {} - async update(id: number, userId: number, updateTaskRequest: UpdateTaskRequest) { const prevTask = await this.findTaskOrThrow(id); const prevSectionId = prevTask.section.id; diff --git a/apps/server/src/task/task.module.ts b/apps/server/src/task/task.module.ts index 9433aa8..4e0c5df 100644 --- a/apps/server/src/task/task.module.ts +++ b/apps/server/src/task/task.module.ts @@ -11,5 +11,6 @@ import { SnapshotController } from '@/task/controller/snapshot.controller'; imports: [TypeOrmModule.forFeature([Task, Section, Project])], controllers: [TaskController, SnapshotController], providers: [TaskService], + exports: [TaskService], }) export class TaskModule {} From 472d4e4aeb0f0d3354640c382eb483703d254ac9 Mon Sep 17 00:00:00 2001 From: yang Date: Mon, 18 Nov 2024 20:36:40 +0900 Subject: [PATCH 3/4] =?UTF-8?q?fix:=20=EB=AF=B8=EA=B5=AC=ED=98=84=20?= =?UTF-8?q?=EB=A9=94=EC=84=9C=EB=93=9C=20=EC=A3=BC=EC=84=9D=20=EC=B2=98?= =?UTF-8?q?=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/server/src/project/controller/project.controller.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/server/src/project/controller/project.controller.ts b/apps/server/src/project/controller/project.controller.ts index 62cb432..66bccac 100644 --- a/apps/server/src/project/controller/project.controller.ts +++ b/apps/server/src/project/controller/project.controller.ts @@ -60,17 +60,17 @@ export class ProjectController { let response; switch (event) { case EventType.CREATE_TASK: - response = await this.taskService.create(user.id, taskEvent); + // response = await this.taskService.create(user.id, taskEvent); break; case EventType.DELETE_TASK: - response = await this.taskService.delete(user.id, taskEvent); + // response = await this.taskService.delete(user.id, taskEvent); break; case EventType.UPDATE_POSITION: - response = await this.taskService.move(user.id, taskEvent); + // response = await this.taskService.move(user.id, taskEvent); break; case EventType.INSERT_TITLE: case EventType.DELETE_TITLE: - response = await this.taskService.update(user.id, taskEvent); + // response = await this.taskService.update(user.id, taskEvent); break; default: throw new BadRequestException('올바르지 않은 이벤트 타입입니다.'); From 6fab0d2cf8efafdb5113d3f0f951acab06ced765 Mon Sep 17 00:00:00 2001 From: yang Date: Mon, 18 Nov 2024 22:16:36 +0900 Subject: [PATCH 4/4] =?UTF-8?q?fix:=20EventEmitter=20Module=EC=9D=84=20?= =?UTF-8?q?=ED=99=9C=EC=9A=A9=ED=95=9C=20Injection=20=EB=B0=A9=EC=8B=9D?= =?UTF-8?q?=EC=9C=BC=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/server/src/app.module.ts | 2 ++ .../{information.type.ts => update-information.type.ts} | 2 +- apps/server/src/task/dto/task-event.dto.ts | 2 +- apps/server/src/task/service/task.service.ts | 5 ++--- 4 files changed, 6 insertions(+), 5 deletions(-) rename apps/server/src/task/domain/{information.type.ts => update-information.type.ts} (69%) diff --git a/apps/server/src/app.module.ts b/apps/server/src/app.module.ts index f9cc4d8..d75551e 100644 --- a/apps/server/src/app.module.ts +++ b/apps/server/src/app.module.ts @@ -11,6 +11,7 @@ import { HttpLoggingInterceptor } from '@/common/httpLog.Interceptor'; import { AllExceptionsFilter } from '@/common/allException.filter'; import { AccountModule } from '@/account/account.module'; import { ProjectModule } from '@/project/project.module'; +import { EventEmitterModule } from '@nestjs/event-emitter'; @Module({ imports: [ @@ -23,6 +24,7 @@ import { ProjectModule } from '@/project/project.module'; return new DataSource(options).initialize(); }, }), + EventEmitterModule.forRoot(), TaskModule, AccountModule, ProjectModule, diff --git a/apps/server/src/task/domain/information.type.ts b/apps/server/src/task/domain/update-information.type.ts similarity index 69% rename from apps/server/src/task/domain/information.type.ts rename to apps/server/src/task/domain/update-information.type.ts index 63a784a..5efa744 100644 --- a/apps/server/src/task/domain/information.type.ts +++ b/apps/server/src/task/domain/update-information.type.ts @@ -1,4 +1,4 @@ -type Information = { +type UpdateInformation = { position: number; content: string; diff --git a/apps/server/src/task/dto/task-event.dto.ts b/apps/server/src/task/dto/task-event.dto.ts index 4c9c0b1..20752d3 100644 --- a/apps/server/src/task/dto/task-event.dto.ts +++ b/apps/server/src/task/dto/task-event.dto.ts @@ -15,5 +15,5 @@ export class TaskEvent { @IsEnum(EventType) event: EventType; - title: Information; + title: UpdateInformation; } diff --git a/apps/server/src/task/service/task.service.ts b/apps/server/src/task/service/task.service.ts index 081eed9..c003466 100644 --- a/apps/server/src/task/service/task.service.ts +++ b/apps/server/src/task/service/task.service.ts @@ -21,8 +21,6 @@ import { EventEmitter2 } from '@nestjs/event-emitter'; export class TaskService { private snapshots: Map = new Map(); private operations: Map = new Map(); - private eventEmitter: EventEmitter2 = new EventEmitter2(); - private connections: Map = new Map(); constructor( @@ -31,7 +29,8 @@ export class TaskService { @InjectRepository(Section) private sectionRepository: Repository
, @InjectRepository(Project) - private projectRepository: Repository + private projectRepository: Repository, + private eventEmitter: EventEmitter2 ) {} addConnection(projectId: number, res: CustomResponse) {