20240319

귤금·2024년 3월 19일

Node.js 4기 TIL

목록 보기
59/86

Today?

조별 프로젝트 : 일잘러

기본 CRUD 기능 구현

컬럼의 순서 이동

컬럼 순서를 배열로 저장하기로 했기 때문에 board의 서비스 계층에 다음과 같이 작성하였다.

const columnOrderArray = JSON.parse(updateColumnOrderDto.columnOrder);
      
if (!Array.isArray(columnOrderArray)) {
	throw new BadRequestException('컬럼 순서 저장 오류가 발생했습니다.');
}

const columnIds = await this.columnRepository.find({
	where: { id: In(columnOrderArray) }
});

이렇게 하면 텍스트로 받아온 데이터를 배열 형식으로 저장할 수 있으며, 올바른 배열 형식의 텍스트가 아닐 경우 에러를 발생시킨다.
만들다보니 예외처리를 해야 할 부분이 굉장히 많았음...

  // ColumnOrder 업데이트
  async updateColumnOrder(boardId: number, updateColumnOrderDto: UpdateColumnOrderDto): Promise<Board> {
    let board;
    try {
      board = await this.boardRepository.findOneBy({ id: BigInt(boardId) });
    } catch (error) {
      throw new BadRequestException('보드 ID가 유효한 숫자 형식이 아닙니다.');
    }
  
    if (!board) {
      throw new NotFoundException("존재하지 않는 보드입니다.");
    }
  
    let columnOrderArray: readonly any[] | FindOperator<any>;
    try {
      columnOrderArray = JSON.parse(updateColumnOrderDto.columnOrder);
    } catch (error) {
      throw new BadRequestException('제공된 컬럼 순서가 유효한 JSON 형식이 아닙니다.');
    }
  
    if (!Array.isArray(columnOrderArray)) {
      throw new BadRequestException('컬럼 순서는 배열이어야 합니다.');
    }
  
    let columnIds: any[];
    try {
      columnIds = await this.columnRepository.find({
        where: { id: In(columnOrderArray) }
      });
    } catch (error) {
      throw new BadRequestException('컬럼 ID 조회 중 문제가 발생했습니다.');
    }
  
    const validColumnIds = columnIds.map(column => column.id.toString()); 
    const isValidColumnOrder = columnOrderArray.every(id => validColumnIds.includes(id.toString())); 

    if (!isValidColumnOrder) {
      throw new BadRequestException('존재하지 않는 컬럼이 지정되었습니다.');
    }
  
    board.columnOrder = JSON.stringify(columnOrderArray);
    try {
      await this.boardRepository.save(board);
    } catch (error) {
      throw new BadRequestException('보드 정보 업데이트 중 오류가 발생했습니다.');
    }
  
    return board;
  }

배열을 저장하는 최종 코드는 이렇게 되었다. 이제 배열을 불러와서 올바른 컬럼 순으로 정렬해주는 방법을 생각해내면 된다.

배열을 통한 정렬

const orderedQuery = this.columnRepository
        .createQueryBuilder('column')
        .where('column.boardId = :boardId', { boardId })
        .orderBy(`FIELD(column.id, ${columnOrderArray.join(',')})`);
        
-- 이 부분을 SQL로 풀어 쓰면
SELECT * FROM column
WHERE column.boardId = 1
ORDER BY FIELD(column.id, '4','2','3');

ORDER BY FIELD(column.id, '4','2','3'); 부분이 배열로 저장된 order 데이터로 정렬하는 부분이다.

const columnOrder = await this.findColumnOrder(boardId);
  const columns = await this.columnRepository.find({
    where: { boardId: boardId },
  });

  const orderedColumns = columnOrder.map(id => columns.find(column => column.id === id)).filter(column => column !== undefined);

  return orderedColumns;

원래 이렇게 map 함수를 사용하는 걸 고려했으나 양이 늘어나면 성능이 저하된다고 하여... 쿼리 빌더로 변경하였다. 그런데 사실 column은 그렇게 많이 생성될 것 같진 않아서 상관없으려나..

알림 기능

알림 기능을 어떻게 구현하면 좋을지 아직도 고민중...


회고

0개의 댓글