From 1c55fde3c365545c98b2546a12f8265a4d4c5545 Mon Sep 17 00:00:00 2001 From: yang Date: Wed, 20 Nov 2024 21:50:25 +0900 Subject: [PATCH] =?UTF-8?q?refactor:=20=EB=B3=91=ED=95=A9=EC=9D=84=20?= =?UTF-8?q?=EC=9C=84=ED=95=9C=20=EB=B3=80=EA=B2=BD=20=EC=82=AC=ED=95=AD=20?= =?UTF-8?q?=EC=A0=80=EC=9E=A5=20=EB=B0=A9=EC=8B=9D=EC=9D=84=20Project=20?= =?UTF-8?q?=EB=8B=A8=EC=9C=84=EC=97=90=EC=84=9C=20Task=20=EB=8B=A8?= =?UTF-8?q?=EC=9C=84=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 --- .../src/task/dto/task-event-response.dto.ts | 15 +--- apps/server/src/task/service/task.service.ts | 88 +++++++++---------- 2 files changed, 43 insertions(+), 60 deletions(-) diff --git a/apps/server/src/task/dto/task-event-response.dto.ts b/apps/server/src/task/dto/task-event-response.dto.ts index f20cbfe..1671961 100644 --- a/apps/server/src/task/dto/task-event-response.dto.ts +++ b/apps/server/src/task/dto/task-event-response.dto.ts @@ -1,22 +1,9 @@ -import { EventType } from '@/task/domain/eventType.enum'; -import { TaskEvent } from '@/task/dto/task-event.dto'; - export class TaskEventResponse { taskId: number; - event: EventType; - - static from(taskEvent: TaskEvent) { - const response = new TaskEventResponse(); - response.taskId = taskEvent.taskId; - response.event = taskEvent.event; - return response; - } - - static of(taskId: number, taskEvent: TaskEvent) { + static from(taskId: number) { const response = new TaskEventResponse(); response.taskId = taskId; - response.event = taskEvent.event; return response; } } diff --git a/apps/server/src/task/service/task.service.ts b/apps/server/src/task/service/task.service.ts index 45e9dbf..788aff8 100644 --- a/apps/server/src/task/service/task.service.ts +++ b/apps/server/src/task/service/task.service.ts @@ -14,14 +14,12 @@ import { MoveTaskResponse } from '@/task/dto/move-task-response.dto'; import { TaskResponse } from '@/task/dto/task-response.dto'; 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 { TaskEvent } from '@/task/dto/task-event.dto'; import { EventType } from '@/task/domain/eventType.enum'; import { Contributor } from '@/project/entity/contributor.entity'; import { BroadcastService } from '@/task/service/broadcast.service'; import { ContributorStatus } from '@/project/enum/contributor-status.enum'; import { TaskEventResponse } from '@/task/dto/task-event-response.dto'; -import { UpdateInformation } from '@/task/domain/update-information.type'; const { defaultType: json0 } = ShareDB.types; @@ -34,8 +32,6 @@ export class TaskService { private taskRepository: Repository, @InjectRepository(Section) private sectionRepository: Repository
, - @InjectRepository(Project) - private projectRepository: Repository, @InjectRepository(Contributor) private contributorRepository: Repository, private broadcastService: BroadcastService, @@ -44,58 +40,53 @@ export class TaskService { this.eventEmitter.on('broadcast', (userId: number, projectId: number, event: TaskEvent) => { this.broadcastService.sendConnection(userId, projectId, event); }); - this.eventEmitter.on('operationAdded', async (userId: number, projectId: number) => { - await this.dequeue(userId, projectId); - }); + this.eventEmitter.on( + 'operationAdded', + async (userId: number, projectId: number, taskId: number) => { + await this.dequeue(userId, projectId, taskId); + } + ); } async enqueue(userId: number, projectId: number, taskEvent: TaskEvent) { - const key = projectId; + const taskId = taskEvent.taskId; const contributor = await this.contributorRepository.findOneBy({ projectId, userId }); if (!contributor || contributor.status !== ContributorStatus.ACCEPTED) { throw new ForbiddenException('Permission denied'); } - const currentEvents = this.operations.get(key) || []; - this.operations.set(key, [...currentEvents, taskEvent]); - this.eventEmitter.emit('operationAdded', userId, projectId); + const currentEvents = this.operations.get(taskId) || []; + this.operations.set(taskId, [...currentEvents, taskEvent]); + this.eventEmitter.emit('operationAdded', userId, projectId, taskId); } - private async dequeue(userId: number, projectId: number) { - const key = projectId; - const taskEvents = this.operations.get(key); - if (!taskEvents) { + private async dequeue(userId: number, projectId: number, taskId: number) { + const taskEventQueue = this.operations.get(taskId); + if (!taskEventQueue) { return; } - let lastOp = []; - while (taskEvents.length) { - const taskEvent = taskEvents.shift(); - const existing = await this.findTaskOrThrow(taskEvent.taskId); - const result = this.merge(taskEvent, existing); - - const transformedOp = lastOp.length ? json0.transform(result, lastOp, 'right') : result; + const initialTask = this.taskRepository.findOneBy({ id: taskId }); + let accumulateOperations = []; + while (taskEventQueue.length) { + const taskEvent = taskEventQueue.shift(); + const operation = this.convertToOperation(taskEvent); - this.taskRepository.save(result); + const transformedOperation = accumulateOperations.length + ? json0.transform(operation, accumulateOperations, 'right') + : operation; - this.eventEmitter.emit('broadcast', userId, projectId, TaskEventResponse.from(taskEvent)); - - lastOp = json0.compose(lastOp, transformedOp); + accumulateOperations = json0.compose(accumulateOperations, transformedOperation); } - } - - private merge(change: TaskEvent, existing: Task) { - const updateTitle = change.title; - const existingTitle = existing.title; - const { event } = change; - const op = this.convertToShareDbOp(event, updateTitle); - const newTitle = json0.apply(existingTitle, op); - - return { ...existing, title: newTitle }; + const newText = json0.apply(initialTask, accumulateOperations); + const result = { ...initialTask, title: newText }; + this.taskRepository.save(result); + this.eventEmitter.emit('broadcast', userId, projectId, TaskEventResponse.from(taskId)); } - private convertToShareDbOp(event: EventType, updateTitle: UpdateInformation) { - const { content, position } = updateTitle; + private convertToOperation(taskEvent: TaskEvent) { + const { event } = taskEvent; + const { content, position } = taskEvent.title; switch (event) { case EventType.INSERT_TITLE: @@ -124,12 +115,7 @@ export class TaskService { section, }); - this.eventEmitter.emit( - 'broadcast', - userId, - projectId, - TaskEventResponse.of(task.id, taskEvent) - ); + this.eventEmitter.emit('broadcast', userId, projectId, TaskEventResponse.from(task.id)); return new CreateTaskResponse(task); } @@ -180,7 +166,12 @@ export class TaskService { task.section = section; await this.taskRepository.save(task); - this.eventEmitter.emit('broadcast', userId, projectId, TaskEventResponse.from(taskEvent)); + this.eventEmitter.emit( + 'broadcast', + userId, + projectId, + TaskEventResponse.from(taskEvent.taskId) + ); return new MoveTaskResponse(task); } @@ -210,7 +201,12 @@ export class TaskService { } await this.taskRepository.delete(taskEvent.taskId); - this.eventEmitter.emit('broadcast', userId, projectId, TaskEventResponse.from(taskEvent)); + this.eventEmitter.emit( + 'broadcast', + userId, + projectId, + TaskEventResponse.from(taskEvent.taskId) + ); return new DeleteTaskResponse(taskEvent.taskId); }