NodeSchedule를 이용한 휴면 계정 기능 구현

김민섭·2022년 11월 20일
0

실전 프로젝트

목록 보기
2/3

항해 99에서 하는 실전 프로젝트 중 로그인 파트에서 1달 동안 이용하지 않은 유저들을 휴면계정으로 바꾸는 기능을 구현했다.

내가 생각한 방법

  1. DB에 LoginHistory (마지막으로 로그인한 기록), expiration (휴면상태인지 아닌지를 표현)
    이렇게 두 가지의 column을 만든다.
  2. 로그인을 할 때마다 그 계정의 LoginHistory를 현재 날짜와 시간으로 업데이트 한다.
  3. 매일 00시 00분 마다 DB에 저장된 모든 유저들의 LoginHistory에 1달을 더한다.
  4. 1달을 더한 값이 현재의 시간보다 과거라면 expiration을 true로 바꿔서 휴면계정으로 만든다.

구현 과정

1번과 2번은 mongoose를 이용한 findOneAndUpdate를 사용하여 평소에 하던 것처럼 손쉽게 할 수 있었기 때문에 생략했다.

3번 같은 경우는 nodeschedule을 이용했다.
nodeschedule의 시간을 매일 00시 00분으로 맞춰놓고 유저 DB에서 마지막 로그인 기록을 가져온 뒤 setMonth를 사용해서 한달을 더해 주었다.

더하는 과정에서 한달을 더해주는 기능은 함수로 따로 만들어서 관리를 해주었다.

// 시간 데이터에 1달을 더하는 함수
const nextMonth = (date) => {
  const newDate = new Date(date);
  newDate.setMonth(newDate.getMonth() + 1);
  return String(newDate);
};

전체 코드

const Members = require("../models/members");
const schedule = require("node-schedule");
const rule = new schedule.RecurrenceRule();

// 시간 데이터에 1달을 더하는 함수
const nextMonth = (date) => {
  const newDate = new Date(date);
  newDate.setMonth(newDate.getMonth() + 1);
  return String(newDate);
};

// 현재 시각
const date = new Date();

/// schedule이 실행되는 시간을 설정하는 rule
rule.dayOfWeek = [0, 1, 2, 3, 4, 5, 6];
rule.hour = 00;
rule.minute = 00;

// rule에서 정의한 대로 매일 정해진 시간마다 스케쥴러 실행
const expiration = schedule.scheduleJob(rule, async () => {
  console.log("스케쥴러 실행");
  
  // expiration 모델에서 모든 유저들의 정보를 가져온다
  const findAllExpiration = await Members.find({});
  const expirationMember = [];

  /**가져온 유저중에서 한달동안 로그인을 하지 않은 유저들을 찾은 뒤
   * expirationMember 배열에 넣는다 */
  for (let i = 0; i < findAllExpiration.length; i++) {
    const userDate = findAllExpiration[i].updatedAt;
    
    if (nextMonth(userDate) < date) {
      expirationMember.push(findAllExpiration[i]);
    }
  }
  
  //expirationMember 배열에 담긴 유저들의 expiration값을 true로 바꾼다
  if (expirationMember[0] !== undefined) {
    for (let i = 0; i < expirationMember.length; i++) {
      await Members.findByIdAndUpdate(expirationMember[i]._id, {
        expiration: "true",
      });
      console.log(
        `${expirationMember[i].memberEmail}의 계정이 일시적으로 정지되었습니다`
      );
    }
  } else {
    console.log("정지할 계정이 없습니다");
  }
});

module.exports = expiration;
profile
getting ready to run

0개의 댓글