diff --git a/apps/server/src/task/domain/update-information.type.ts b/apps/server/src/task/domain/update-information.type.ts index bbb643c..f2d395c 100644 --- a/apps/server/src/task/domain/update-information.type.ts +++ b/apps/server/src/task/domain/update-information.type.ts @@ -1,7 +1,15 @@ -export type UpdateInformation = { +import { IsNumber, IsOptional, IsString } from 'class-validator'; + +export class UpdateInformation { + @IsOptional() + @IsNumber() position: number; + @IsOptional() + @IsString() content: string; + @IsOptional() + @IsNumber() length: number; -}; +} 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 8f65b7d..f20cbfe 100644 --- a/apps/server/src/task/dto/task-event-response.dto.ts +++ b/apps/server/src/task/dto/task-event-response.dto.ts @@ -6,8 +6,17 @@ export class TaskEventResponse { event: EventType; - constructor(taskEvent: TaskEvent) { - this.taskId = taskEvent.taskId; - this.event = taskEvent.event; + static from(taskEvent: TaskEvent) { + const response = new TaskEventResponse(); + response.taskId = taskEvent.taskId; + response.event = taskEvent.event; + return response; + } + + static of(taskId: number, taskEvent: TaskEvent) { + const response = new TaskEventResponse(); + response.taskId = taskId; + response.event = taskEvent.event; + return response; } } diff --git a/apps/server/src/task/dto/task-event.dto.ts b/apps/server/src/task/dto/task-event.dto.ts index bc0829c..72b7a78 100644 --- a/apps/server/src/task/dto/task-event.dto.ts +++ b/apps/server/src/task/dto/task-event.dto.ts @@ -1,14 +1,25 @@ -import { IsNumber, IsNotEmpty, IsString, IsEnum } from 'class-validator'; +import { + IsNumber, + IsNotEmpty, + IsString, + IsEnum, + ValidateNested, + IsOptional, +} from 'class-validator'; +import { Type } from 'class-transformer'; import { EventType } from '@/task/domain/eventType.enum'; import { UpdateInformation } from '@/task/domain/update-information.type'; export class TaskEvent { + @IsOptional() @IsNumber() taskId: number; + @IsOptional() @IsNumber() sectionId: number; + @IsOptional() @IsString() position: string; @@ -16,5 +27,8 @@ export class TaskEvent { @IsEnum(EventType) event: EventType; + @IsOptional() + @ValidateNested() + @Type(() => UpdateInformation) title: UpdateInformation; } diff --git a/apps/server/src/task/service/task.service.ts b/apps/server/src/task/service/task.service.ts index 34672e3..c591db9 100644 --- a/apps/server/src/task/service/task.service.ts +++ b/apps/server/src/task/service/task.service.ts @@ -23,7 +23,7 @@ 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 { json0 } = ShareDB.types; +const json0 = ShareDB.types.defaultType; @Injectable() export class TaskService { @@ -73,13 +73,13 @@ export class TaskService { const existing = await this.findTaskOrThrow(taskEvent.taskId); const result = this.merge(taskEvent, existing); - const transformedOp = lastOp.length ? json0.type.transform(result, lastOp, 'right') : result; + const transformedOp = lastOp.length ? json0.transform(result, lastOp, 'right') : result; this.taskRepository.save(result); - this.eventEmitter.emit('broadcast', userId, projectId, new TaskEventResponse(taskEvent)); + this.eventEmitter.emit('broadcast', userId, projectId, TaskEventResponse.from(taskEvent)); - lastOp = json0.type.compose(lastOp, transformedOp); + lastOp = json0.compose(lastOp, transformedOp); } } @@ -87,9 +87,10 @@ export class TaskService { const updateTitle = change.title; const existingTitle = existing.title; const { event } = change; + console.log(change); const op = this.convertToShareDbOp(event, updateTitle); - const newTitle = json0.type.apply(existingTitle, op); + const newTitle = json0.apply(existingTitle, op); return { ...existing, title: newTitle }; } @@ -101,12 +102,7 @@ export class TaskService { case EventType.INSERT_TITLE: return [{ p: [position], si: content }]; case EventType.DELETE_TITLE: - return [ - { - p: [position], - sd: content, - }, - ]; + return [{ p: [position], sd: content }]; default: throw new BadRequestException('Invalid event type'); } @@ -129,7 +125,12 @@ export class TaskService { section, }); - this.eventEmitter.emit('broadcast', userId, projectId, new TaskEventResponse(taskEvent)); + this.eventEmitter.emit( + 'broadcast', + userId, + projectId, + TaskEventResponse.of(task.id, taskEvent) + ); return new CreateTaskResponse(task); } @@ -180,7 +181,7 @@ export class TaskService { task.section = section; await this.taskRepository.save(task); - this.eventEmitter.emit('broadcast', userId, projectId, new TaskEventResponse(taskEvent)); + this.eventEmitter.emit('broadcast', userId, projectId, TaskEventResponse.from(taskEvent)); return new MoveTaskResponse(task); } @@ -210,7 +211,7 @@ export class TaskService { } await this.taskRepository.delete(taskEvent.taskId); - this.eventEmitter.emit('broadcast', userId, projectId, new TaskEventResponse(taskEvent)); + this.eventEmitter.emit('broadcast', userId, projectId, TaskEventResponse.from(taskEvent)); return new DeleteTaskResponse(taskEvent.taskId); }