명예의 전당 리팩토링 해보기(1)

JinYoungMo·2024년 3월 30일
// 투표 데이터 집계 함수
  private async aggVotesForHallOfFame(votes: Votes[]){
    const candidates = await this.votesRepository
    .createQueryBuilder("vote")
    .select(['vote.id', 'vote.title1', 'vote.title2'])
    .addSelect("vote.voteCount1 + vote.voteCount2", "totalVotes")
    .having("totalVotes >= :minTotalVotes", { minTotalVotes: 100 }) // 투표 수 100 이상인 것만 조회
    .groupBy("vote.id")
    .getRawMany();

    return candidates
  }

기존 로직은 이렇게 되었다..

하지만 퀴러빌더 문에서 데이터를 조회할 때 굳이 이번달에 아닌 날에 작성된 투표 데이터를 조회할 필요까지 없어 보였다. 아니 명확했다.

따라서 내가 업데이트 하는 날짜의 해당하는 달의 데이터만 조회하기로 하였다.

리팩토링 코드는 다음과 같다.

private async aggVotesForHallOfFame(votes: Votes[]){
  const candidates = await this.votesRepository
  .createQueryBuilder("vote")
  .select(['vote.id', 'vote.title1', 'vote.title2'])
  .addSelect("vote.voteCount1 + vote.voteCount2", "totalVotes")
  .where("vote.createdAt BETWEEN :start AND :end", { start: '2024-03-01', end: '2024-03-31' }) // 특정 기간을 정의
  .having("totalVotes >= :minTotalVotes", { minTotalVotes: 100 }) // 투표 수 100 이상인 것만 조회
  .groupBy("vote.id")
  .getRawMany();

  return candidates;
}

기존에는 없던 where문을 추가하여서 현재 해당하는 달만 조회하기로 하였다
vote.createAt BETWEEN :start AND :end { start: '2024-03-01', end: '2024-03-31' })를 통해서 조건을 좁혔다. 하지만 이렇게 되어도 이상하게 찜찜하였다.

바로 start와 end를 직접 하드코딩해야한다는 점이였다.

그래서 한번 더 리팩토링 하였다

추상화한 코드
// 날짜 추상화 매서드
  private getThisMonthRange(){
    const start = new Date();
    start.setDate(1); // 이번달 첫쨰날
    start.setHours(0, 0, 0, 0) // 자정

    const end = new Date(start.getFullYear(), start.getMonth() + 1, 0);
    end.setHours(23, 59, 59, 999) // 하루의 마지막 시간

    return { start, end }
  }
  // 투표 데이터 집계 매서드
  private async aggVotesForHallOfFame(votes: Votes[]){
    const { start, end } = this.getThisMonthRange();

    const candidates = await this.votesRepository
    .createQueryBuilder("vote")
    .select(['vote.id', 'vote.title1', 'vote.title2'])
    .addSelect("vote.voteCount1 + vote.voteCount2", "totalVotes")
    .where('vote.createdAt BETWEEN :start AND :end', { start: start.toISOString(), end: end.toISOString() })
    .having("totalVotes >= :minTotalVotes", { minTotalVotes: 100 }) // 투표 수 100 이상인 것만 조회
    .groupBy("vote.id")
    .getRawMany();

    return candidates
  }

start와 end 하드코딩하지않고 모듈화 시켰다

profile
blockchain core & payments and stable coins

0개의 댓글