diff --git a/apps/backend/src/edge/edge.controller.spec.ts b/apps/backend/src/edge/edge.controller.spec.ts index 00364901..bac52001 100644 --- a/apps/backend/src/edge/edge.controller.spec.ts +++ b/apps/backend/src/edge/edge.controller.spec.ts @@ -81,6 +81,7 @@ describe('EdgeController', () => { id: 3, x: 0, y: 0, + color: '#FFFFFF', title: 'Node Title', page: null, outgoingEdges: [], @@ -91,6 +92,7 @@ describe('EdgeController', () => { id: 4, x: 0, y: 0, + color: '#FFFFFF', title: 'Node Title', page: null, outgoingEdges: [], @@ -101,6 +103,7 @@ describe('EdgeController', () => { id: 5, x: 0, y: 0, + color: '#FFFFFF', title: 'Node Title', page: null, outgoingEdges: [], diff --git a/apps/backend/src/edge/edge.service.spec.ts b/apps/backend/src/edge/edge.service.spec.ts index 51946a1a..9f2d5da2 100644 --- a/apps/backend/src/edge/edge.service.spec.ts +++ b/apps/backend/src/edge/edge.service.spec.ts @@ -64,6 +64,7 @@ describe('EdgeService', () => { id: 3, x: 0, y: 0, + color: '#FFFFFF', title: 'Node Title', page: null, outgoingEdges: [], @@ -74,6 +75,7 @@ describe('EdgeService', () => { id: 5, x: 0, y: 0, + color: '#FFFFFF', title: 'Node Title', page: null, outgoingEdges: [], @@ -143,6 +145,7 @@ describe('EdgeService', () => { id: 3, x: 0, y: 0, + color: '#FFFFFF', title: 'Node Title', page: null, outgoingEdges: [], @@ -153,6 +156,7 @@ describe('EdgeService', () => { id: 4, x: 0, y: 0, + color: '#FFFFFF', title: 'Node Title', page: null, outgoingEdges: [], @@ -163,6 +167,7 @@ describe('EdgeService', () => { id: 5, x: 0, y: 0, + color: '#FFFFFF', title: 'Node Title', page: null, outgoingEdges: [], @@ -173,6 +178,7 @@ describe('EdgeService', () => { id: 7, x: 0, y: 0, + color: '#FFFFFF', title: 'Node Title', page: null, outgoingEdges: [], diff --git a/apps/backend/src/node/node.entity.ts b/apps/backend/src/node/node.entity.ts index c97f94c0..d047ed7d 100644 --- a/apps/backend/src/node/node.entity.ts +++ b/apps/backend/src/node/node.entity.ts @@ -23,6 +23,9 @@ export class Node { @Column('float') y: number; + @Column({ default: '#FFFFFF' }) + color: string; + @OneToOne(() => Page, (page) => page.node, { cascade: true, onDelete: 'CASCADE', diff --git a/apps/backend/src/node/node.service.spec.ts b/apps/backend/src/node/node.service.spec.ts index f880f8c6..e0207f6f 100644 --- a/apps/backend/src/node/node.service.spec.ts +++ b/apps/backend/src/node/node.service.spec.ts @@ -70,6 +70,7 @@ describe('NodeService', () => { id: 1, x: 0, y: 0, + color: '#FFFFFF', title: 'Node Title', page: null, outgoingEdges: [], @@ -185,6 +186,7 @@ describe('NodeService', () => { id: 1, x: 0, y: 0, + color: '#FFFFFF', title: 'Node Title', page: null, outgoingEdges: [], diff --git a/apps/backend/src/page/page.service.spec.ts b/apps/backend/src/page/page.service.spec.ts index df291830..4f5430ed 100644 --- a/apps/backend/src/page/page.service.spec.ts +++ b/apps/backend/src/page/page.service.spec.ts @@ -120,6 +120,7 @@ describe('PageService', () => { id: 1, x: 0, y: 0, + color: '#FFFFFF', page: null, outgoingEdges: [], incomingEdges: [], diff --git a/apps/backend/src/redis/redis.service.ts b/apps/backend/src/redis/redis.service.ts index a9e5e310..de1a41f3 100644 --- a/apps/backend/src/redis/redis.service.ts +++ b/apps/backend/src/redis/redis.service.ts @@ -12,8 +12,9 @@ export type RedisPage = { }; export type RedisNode = { - x: number; - y: number; + x?: number; + y?: number; + color?: string; }; export type RedisEdge = { diff --git a/apps/backend/src/tasks/tasks.service.ts b/apps/backend/src/tasks/tasks.service.ts index 840fa6d3..e6669212 100644 --- a/apps/backend/src/tasks/tasks.service.ts +++ b/apps/backend/src/tasks/tasks.service.ts @@ -113,10 +113,12 @@ export class TasksService { throw new Error(`redis에 ${key}에 해당하는 데이터가 없습니다.`); } - const updateData: Partial = { - x: Number(redisData.x), - y: Number(redisData.y), - }; + const { x, y, color } = redisData; + const updateData: Partial = {}; + + if (x) updateData.x = Number(x); + if (y) updateData.y = Number(y); + if (color) updateData.color = color; // 쿼리 대상이 없다면 리턴 if (Object.keys(updateData).length === 0) return; @@ -142,8 +144,12 @@ export class TasksService { // 실패하면 postgres는 roll back하고 redis의 값을 살린다. this.logger.error(err.stack); await queryRunner.rollbackTransaction(); - await this.redisService.setField(key, 'x', updateData.x.toString()); - await this.redisService.setField(key, 'y', updateData.y.toString()); + updateData.x && + (await this.redisService.setField(key, 'x', updateData.x.toString())); + updateData.y && + (await this.redisService.setField(key, 'y', updateData.y.toString())); + updateData.color && + (await this.redisService.setField(key, 'color', updateData.color)); // Promise.all에서 실패를 인식하기 위해 에러를 던진다. throw err; diff --git a/apps/websocket/src/yjs/types/node.entity.ts b/apps/websocket/src/yjs/types/node.entity.ts index 8670a3a2..1d8f3bb5 100644 --- a/apps/websocket/src/yjs/types/node.entity.ts +++ b/apps/websocket/src/yjs/types/node.entity.ts @@ -8,6 +8,8 @@ export class Node { y: number; + color: string; + page: Page; outgoingEdges: Edge[]; diff --git a/apps/websocket/src/yjs/yjs.service.ts b/apps/websocket/src/yjs/yjs.service.ts index 7ff416bc..9edb535c 100644 --- a/apps/websocket/src/yjs/yjs.service.ts +++ b/apps/websocket/src/yjs/yjs.service.ts @@ -187,6 +187,7 @@ export class YjsService x: node.x, y: node.y, }, + color: node.color ?? '#FFFFFF', selected: false, // 기본적으로 선택되지 않음 dragging: true, isHolding: false, @@ -266,21 +267,21 @@ export class YjsService const { id } = node.data; const { x, y } = node.position; const isHolding = node.isHolding; + const color = node.color ?? '#FFFFFF'; if (isHolding) continue; - // TODO : node의 경우 key 값을 page id가 아닌 node id로 변경 - // const findPage = await this.pageService.findPageById(id); - // await this.nodeService.updateNode(findPage.node.id, { - // title, - // x, - // y, - // }); const pageResponse = await axios.get( `http://backend:3000/api/page/${id}`, ); const findPage = pageResponse.data.page; - this.redisService.setField(`node:${findPage.node.id}`, 'x', x); - this.redisService.setField(`node:${findPage.node.id}`, 'y', y); + + await this.redisService.setField(`node:${findPage.node.id}`, 'x', x); + await this.redisService.setField(`node:${findPage.node.id}`, 'y', y); + await this.redisService.setField( + `node:${findPage.node.id}`, + 'color', + color, + ); } } diff --git a/apps/websocket/src/yjs/yjs.type.ts b/apps/websocket/src/yjs/yjs.type.ts index a250007b..3484e74d 100644 --- a/apps/websocket/src/yjs/yjs.type.ts +++ b/apps/websocket/src/yjs/yjs.type.ts @@ -11,6 +11,7 @@ export type YMapNode = { x: number; // X 좌표 y: number; // Y 좌표 }; + color: string; // 색상 selected: boolean; isHolding: boolean; };